update dev300-m58
[ooovba.git] / dbaccess / source / ext / macromigration / migrationengine.cxx
blobcf8acb01e6b99ba0809b8d5f5c28ab53fb6cea33
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: migrationengine.cxx,v $
10 * $Revision: 1.4.2.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dbaccess.hxx"
34 #include "dbmm_global.hrc"
35 #include "dbmm_module.hxx"
36 #include "dbmm_types.hxx"
37 #include "docinteraction.hxx"
38 #include "migrationengine.hxx"
39 #include "migrationerror.hxx"
40 #include "migrationprogress.hxx"
41 #include "migrationlog.hxx"
42 #include "progresscapture.hxx"
43 #include "progressmixer.hxx"
45 /** === begin UNO includes === **/
46 #include <com/sun/star/sdb/XFormDocumentsSupplier.hpp>
47 #include <com/sun/star/sdb/XReportDocumentsSupplier.hpp>
48 #include <com/sun/star/util/XCloseable.hpp>
49 #include <com/sun/star/frame/XModel.hpp>
50 #include <com/sun/star/frame/XComponentLoader.hpp>
51 #include <com/sun/star/ucb/XCommandProcessor.hpp>
52 #include <com/sun/star/ucb/XContent.hpp>
53 #include <com/sun/star/embed/XComponentSupplier.hpp>
54 #include <com/sun/star/embed/ElementModes.hpp>
55 #include <com/sun/star/document/XStorageBasedDocument.hpp>
56 #include <com/sun/star/embed/XTransactedObject.hpp>
57 #include <com/sun/star/frame/XStorable.hpp>
58 #include <com/sun/star/embed/XEmbedPersist.hpp>
59 #include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
60 #include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
61 #include <com/sun/star/document/XEmbeddedScripts.hpp>
62 #include <com/sun/star/document/XEventsSupplier.hpp>
63 #include <com/sun/star/uri/UriReferenceFactory.hpp>
64 #include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
65 #include <com/sun/star/form/XFormsSupplier.hpp>
66 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
67 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
68 #include <com/sun/star/script/XEventAttacherManager.hpp>
69 #include <com/sun/star/script/XLibraryContainerPassword.hpp>
70 #include <com/sun/star/io/WrongFormatException.hpp>
71 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
72 #include <com/sun/star/io/XInputStreamProvider.hpp>
73 /** === end UNO includes === **/
75 #include <comphelper/documentinfo.hxx>
76 #include <comphelper/interaction.hxx>
77 #include <comphelper/namedvaluecollection.hxx>
78 #include <comphelper/storagehelper.hxx>
79 #include <comphelper/string.hxx>
80 #include <comphelper/types.hxx>
81 #include <cppuhelper/exc_hlp.hxx>
82 #include <tools/string.hxx>
83 #include <tools/diagnose_ex.h>
84 #include <rtl/ustrbuf.hxx>
85 #include <rtl/ref.hxx>
86 #include <unotools/sharedunocomponent.hxx>
87 #include <xmlscript/xmldlg_imexp.hxx>
89 #include <vector>
90 #include <set>
92 #define DEFAULT_DOC_PROGRESS_RANGE 100000
94 //........................................................................
95 namespace dbmm
97 //........................................................................
99 /** === begin UNO using === **/
100 using ::com::sun::star::uno::Reference;
101 using ::com::sun::star::uno::XInterface;
102 using ::com::sun::star::uno::UNO_QUERY;
103 using ::com::sun::star::uno::UNO_QUERY_THROW;
104 using ::com::sun::star::uno::UNO_SET_THROW;
105 using ::com::sun::star::uno::Exception;
106 using ::com::sun::star::uno::RuntimeException;
107 using ::com::sun::star::uno::Any;
108 using ::com::sun::star::uno::makeAny;
109 using ::com::sun::star::sdb::XOfficeDatabaseDocument;
110 using ::com::sun::star::sdb::XFormDocumentsSupplier;
111 using ::com::sun::star::sdb::XReportDocumentsSupplier;
112 using ::com::sun::star::container::XNameAccess;
113 using ::com::sun::star::uno::Sequence;
114 using ::com::sun::star::util::XCloseable;
115 using ::com::sun::star::util::CloseVetoException;
116 using ::com::sun::star::lang::XComponent;
117 using ::com::sun::star::frame::XModel;
118 using ::com::sun::star::frame::XComponentLoader;
119 using ::com::sun::star::ucb::XCommandProcessor;
120 using ::com::sun::star::ucb::XContent;
121 using ::com::sun::star::ucb::Command;
122 using ::com::sun::star::embed::XComponentSupplier;
123 using ::com::sun::star::task::XStatusIndicator;
124 using ::com::sun::star::embed::XStorage;
125 using ::com::sun::star::document::XStorageBasedDocument;
126 using ::com::sun::star::embed::XTransactedObject;
127 using ::com::sun::star::frame::XStorable;
128 using ::com::sun::star::embed::XEmbedPersist;
129 using ::com::sun::star::script::DocumentDialogLibraryContainer;
130 using ::com::sun::star::script::DocumentScriptLibraryContainer;
131 using ::com::sun::star::script::XStorageBasedLibraryContainer;
132 using ::com::sun::star::document::XEmbeddedScripts;
133 using ::com::sun::star::container::XNameContainer;
134 using ::com::sun::star::document::XEventsSupplier;
135 using ::com::sun::star::container::XNameReplace;
136 using com::sun::star::uri::UriReferenceFactory;
137 using com::sun::star::uri::XUriReferenceFactory;
138 using com::sun::star::uri::XVndSunStarScriptUrlReference;
139 using ::com::sun::star::form::XFormsSupplier;
140 using ::com::sun::star::drawing::XDrawPageSupplier;
141 using ::com::sun::star::drawing::XDrawPagesSupplier;
142 using ::com::sun::star::drawing::XDrawPage;
143 using ::com::sun::star::drawing::XDrawPages;
144 using ::com::sun::star::container::XIndexAccess;
145 using ::com::sun::star::script::XEventAttacherManager;
146 using ::com::sun::star::script::ScriptEventDescriptor;
147 using ::com::sun::star::script::XLibraryContainerPassword;
148 using ::com::sun::star::io::WrongFormatException;
149 using ::com::sun::star::script::XScriptEventsSupplier;
150 using ::com::sun::star::io::XInputStreamProvider;
151 using ::com::sun::star::io::XInputStream;
152 /** === end UNO using === **/
153 namespace ElementModes = ::com::sun::star::embed::ElementModes;
155 // migration phases whose progresses are to be mixed into one progress
156 #define PHASE_JAVASCRIPT 1
157 #define PHASE_BEANSHELL 2
158 #define PHASE_PYTHON 3
159 #define PHASE_JAVA 4
160 #define PHASE_BASIC 5
161 #define PHASE_DIALOGS 6
163 //====================================================================
164 //= SubDocument
165 //====================================================================
166 struct SubDocument
168 Reference< XCommandProcessor > xCommandProcessor;
169 Reference< XModel > xDocument; // valid only temporarily
170 ::rtl::OUString sHierarchicalName;
171 SubDocumentType eType;
172 size_t nNumber;
174 SubDocument( const Reference< XCommandProcessor >& _rxCommandProcessor, const ::rtl::OUString& _rName,
175 const SubDocumentType _eType, const size_t _nNumber )
176 :xCommandProcessor( _rxCommandProcessor )
177 ,xDocument()
178 ,sHierarchicalName( _rName )
179 ,eType( _eType )
180 ,nNumber( _nNumber )
185 typedef ::std::vector< SubDocument > SubDocuments;
187 //====================================================================
188 //= helper
189 //====================================================================
190 //--------------------------------------------------------------------
191 typedef ::utl::SharedUNOComponent< XStorage > SharedStorage;
193 namespace
195 //----------------------------------------------------------------
196 static const ::rtl::OUString& lcl_getScriptsStorageName()
198 static const ::rtl::OUString s_sScriptsStorageName( RTL_CONSTASCII_USTRINGPARAM( "Scripts" ) );
199 return s_sScriptsStorageName;
202 //----------------------------------------------------------------
203 static const ::rtl::OUString& lcl_getScriptsSubStorageName( const ScriptType _eType )
205 static const ::rtl::OUString s_sBeanShell ( RTL_CONSTASCII_USTRINGPARAM( "beanshell" ) );
206 static const ::rtl::OUString s_sJavaScript( RTL_CONSTASCII_USTRINGPARAM( "javascript" ) );
207 static const ::rtl::OUString s_sPython ( RTL_CONSTASCII_USTRINGPARAM( "python" ) ); // TODO: is this correct?
208 static const ::rtl::OUString s_sJava ( RTL_CONSTASCII_USTRINGPARAM( "java" ) );
210 switch ( _eType )
212 case eBeanShell: return s_sBeanShell;
213 case eJavaScript: return s_sJavaScript;
214 case ePython: return s_sPython;
215 case eJava: return s_sJava;
216 default:
217 break;
220 OSL_ENSURE( false, "lcl_getScriptsSubStorageName: illegal type!" );
221 static ::rtl::OUString s_sEmpty;
222 return s_sEmpty;
225 //----------------------------------------------------------------
226 static bool lcl_getScriptTypeFromLanguage( const ::rtl::OUString& _rLanguage, ScriptType& _out_rScriptType )
228 struct LanguageMapping
230 const sal_Char* pAsciiLanguage;
231 const ScriptType eScriptType;
233 LanguageMapping( const sal_Char* _pAsciiLanguage, const ScriptType _eScriptType )
234 :pAsciiLanguage( _pAsciiLanguage )
235 ,eScriptType( _eScriptType )
239 aLanguageMapping[] =
241 LanguageMapping( "JavaScript", eJavaScript ),
242 LanguageMapping( "BeanShell", eBeanShell ),
243 LanguageMapping( "Java", eJava ),
244 LanguageMapping( "Python", ePython ), // TODO: is this correct?
245 LanguageMapping( "Basic", eBasic )
247 for ( size_t i=0; i < sizeof( aLanguageMapping ) / sizeof( aLanguageMapping[0] ); ++i )
249 if ( _rLanguage.equalsAscii( aLanguageMapping[i].pAsciiLanguage ) )
251 _out_rScriptType = aLanguageMapping[i].eScriptType;
252 return true;
255 OSL_ENSURE( false, "lcl_getScriptTypeFromLanguage: unknown language!" );
256 return false;
259 //----------------------------------------------------------------
260 ::rtl::OUString lcl_getSubDocumentDescription( const SubDocument& _rDocument )
262 ::rtl::OUString sObjectName = String( MacroMigrationResId( _rDocument.eType == eForm ? STR_FORM : STR_REPORT ) );
263 ::comphelper::string::searchAndReplaceAsciiI( sObjectName, "$name$", _rDocument.sHierarchicalName );
264 return sObjectName;
267 //----------------------------------------------------------------
268 static Any lcl_executeCommand_throw( const Reference< XCommandProcessor >& _rxCommandProc,
269 const sal_Char* _pAsciiCommand )
271 OSL_PRECOND( _rxCommandProc.is(), "lcl_executeCommand_throw: illegal object!" );
272 if ( !_rxCommandProc.is() )
273 return Any();
275 Command aCommand;
276 aCommand.Name = ::rtl::OUString::createFromAscii( _pAsciiCommand );
277 return _rxCommandProc->execute(
278 aCommand, _rxCommandProc->createCommandIdentifier(), NULL );
281 //----------------------------------------------------------------
282 ::rtl::OUString lcl_getMimeType_nothrow( const Reference< XCommandProcessor >& _rxContent )
284 ::rtl::OUString sMimeType;
287 Reference< XContent > xContent( _rxContent, UNO_QUERY_THROW );
288 sMimeType = xContent->getContentType();
290 catch( const Exception& )
292 DBG_UNHANDLED_EXCEPTION();
294 return sMimeType;
297 //----------------------------------------------------------------
298 enum OpenDocResult
300 eOpenedDoc,
301 eIgnoreDoc,
302 eFailure
305 //----------------------------------------------------------------
306 static OpenDocResult lcl_loadSubDocument_nothrow( SubDocument& _rDocument,
307 const Reference< XStatusIndicator >& _rxProgress, MigrationLog& _rLogger )
309 OSL_PRECOND( !_rDocument.xDocument.is(), "lcl_loadSubDocument_nothrow: already loaded!" );
313 ::comphelper::NamedValueCollection aLoadArgs;
314 aLoadArgs.put( "Hidden", (sal_Bool)sal_True );
315 aLoadArgs.put( "StatusIndicator", _rxProgress );
317 Reference< XCommandProcessor > xCommandProcessor( _rDocument.xCommandProcessor, UNO_SET_THROW );
318 Command aCommand;
319 aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "openDesign" ) );
320 aCommand.Argument <<= aLoadArgs.getPropertyValues();
321 Reference< XComponent > xDocComponent(
322 xCommandProcessor->execute(
323 aCommand, xCommandProcessor->createCommandIdentifier(), NULL
325 UNO_QUERY
327 OSL_ENSURE( xDocComponent.is(), "lcl_loadSubDocument_nothrow: no component loaded!" );
329 _rDocument.xDocument.set( xDocComponent, UNO_QUERY_THROW );
331 catch( const Exception& )
333 Any aError( ::cppu::getCaughtException() );
335 bool bCausedByNewStyleReport =
336 ( _rDocument.eType == eReport )
337 && ( aError.isExtractableTo( ::cppu::UnoType< WrongFormatException >::get() ) )
338 && ( lcl_getMimeType_nothrow( _rDocument.xCommandProcessor ).equalsAscii( "application/vnd.sun.xml.report" ) );
340 if ( bCausedByNewStyleReport )
342 _rLogger.logRecoverable( MigrationError(
343 ERR_NEW_STYLE_REPORT,
344 lcl_getSubDocumentDescription( _rDocument )
345 ) );
346 return eIgnoreDoc;
348 else
350 _rLogger.logFailure( MigrationError(
351 ERR_OPENING_SUB_DOCUMENT_FAILED,
352 lcl_getSubDocumentDescription( _rDocument ),
353 aError
354 ) );
357 return _rDocument.xDocument.is() ? eOpenedDoc : eFailure;
360 //----------------------------------------------------------------
361 static bool lcl_unloadSubDocument_nothrow( SubDocument& _rDocument, MigrationLog& _rLogger )
363 bool bSuccess = false;
364 Any aException;
367 OSL_VERIFY( lcl_executeCommand_throw( _rDocument.xCommandProcessor, "close" ) >>= bSuccess );
369 catch( const Exception& )
371 aException = ::cppu::getCaughtException();
374 // log the failure, if any
375 if ( !bSuccess )
377 _rLogger.logFailure( MigrationError(
378 ERR_CLOSING_SUB_DOCUMENT_FAILED,
379 lcl_getSubDocumentDescription( _rDocument ),
380 aException
381 ) );
384 _rDocument.xDocument.clear();
385 return bSuccess;
388 //----------------------------------------------------------------
389 bool lcl_commitStorage_nothrow( const Reference< XStorage >& _rxStorage )
393 Reference< XTransactedObject > xTrans( _rxStorage, UNO_QUERY_THROW );
394 xTrans->commit();
396 catch( const Exception& )
398 return false;
400 return true;
403 //----------------------------------------------------------------
404 bool lcl_commitDocumentStorage_nothrow( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
406 bool bSuccess = false;
407 Any aException;
410 Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
411 Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
412 bSuccess = lcl_commitStorage_nothrow( xDocStorage );
414 catch( const Exception& )
416 aException = ::cppu::getCaughtException();
419 // log the failure, if any
420 if ( !bSuccess )
422 _rLogger.logFailure( MigrationError(
423 ERR_STORAGE_COMMIT_FAILED,
424 ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
425 aException
426 ) );
428 return bSuccess;
431 //----------------------------------------------------------------
432 bool lcl_storeDocument_nothrow( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
434 bool bSuccess = false;
435 Any aException;
438 Reference< XStorable > xStorable( _rxDocument, UNO_QUERY_THROW );
439 xStorable->store();
440 bSuccess = true;
442 catch( const Exception& )
444 aException = ::cppu::getCaughtException();
447 // log the failure, if any
448 if ( !bSuccess )
450 _rLogger.logFailure( MigrationError(
451 ERR_STORING_DATABASEDOC_FAILED,
452 aException
453 ) );
455 return bSuccess;
458 //----------------------------------------------------------------
459 bool lcl_storeEmbeddedDocument_nothrow( const SubDocument& _rDocument )
463 lcl_executeCommand_throw( _rDocument.xCommandProcessor, "store" );
465 catch( const Exception& )
467 DBG_UNHANDLED_EXCEPTION();
468 return false;
470 return true;
474 //====================================================================
475 //= DrawPageIterator
476 //====================================================================
477 class DrawPageIterator
479 public:
480 DrawPageIterator( const Reference< XModel >& _rxDocument )
481 :m_xDocument( _rxDocument )
482 ,m_nPageCount( 0 )
483 ,m_nCurrentPage( 0 )
485 Reference< XDrawPageSupplier > xSingle( _rxDocument, UNO_QUERY );
486 Reference< XDrawPagesSupplier > xMulti( _rxDocument, UNO_QUERY );
487 if ( xSingle.is() )
489 m_xSinglePage.set( xSingle->getDrawPage(), UNO_SET_THROW );
490 m_nPageCount = 1;
492 else if ( xMulti.is() )
494 m_xMultiPages.set( xMulti->getDrawPages(), UNO_SET_THROW );
495 m_nPageCount = m_xMultiPages->getCount();
499 bool hasMore() const
501 return m_nCurrentPage < m_nPageCount;
504 Reference< XDrawPage > next()
506 Reference< XDrawPage > xNextPage;
508 if ( m_xSinglePage.is() )
510 xNextPage = m_xSinglePage;
512 else if ( m_xMultiPages.is() )
514 xNextPage.set( m_xMultiPages->getByIndex( m_nCurrentPage ), UNO_QUERY_THROW );
516 ++m_nCurrentPage;
517 return xNextPage;
520 private:
521 const Reference< XModel > m_xDocument;
522 Reference< XDrawPage > m_xSinglePage;
523 Reference< XDrawPages > m_xMultiPages;
524 sal_Int32 m_nPageCount;
525 sal_Int32 m_nCurrentPage;
528 //====================================================================
529 //= FormComponentScripts
530 //====================================================================
531 class FormComponentScripts
533 public:
534 FormComponentScripts(
535 const Reference< XInterface >& _rxComponent,
536 const Reference< XEventAttacherManager >& _rxManager,
537 const sal_Int32 _nIndex
539 :m_xComponent( _rxComponent, UNO_SET_THROW )
540 ,m_xManager( _rxManager, UNO_SET_THROW )
541 ,m_nIndex( _nIndex )
545 Sequence< ScriptEventDescriptor > getEvents() const
547 return m_xManager->getScriptEvents( m_nIndex );
550 void setEvents( const Sequence< ScriptEventDescriptor >& _rEvents ) const
552 m_xManager->registerScriptEvents( m_nIndex, _rEvents );
555 const Reference< XInterface >& getComponent() const
557 return m_xComponent;
560 private:
561 const Reference< XInterface > m_xComponent;
562 const Reference< XEventAttacherManager > m_xManager;
563 const sal_Int32 m_nIndex;
566 //====================================================================
567 //= FormComponentIterator
568 //====================================================================
569 class FormComponentIterator
571 public:
572 FormComponentIterator( const Reference< XIndexAccess >& _rxContainer )
573 :m_xContainer( _rxContainer, UNO_SET_THROW )
574 ,m_xEventManager( _rxContainer, UNO_QUERY_THROW )
575 ,m_nElementCount( _rxContainer->getCount() )
576 ,m_nCurrentElement( 0 )
580 bool hasMore() const
582 return m_nCurrentElement < m_nElementCount;
585 FormComponentScripts next()
587 FormComponentScripts aComponent(
588 Reference< XInterface >( m_xContainer->getByIndex( m_nCurrentElement ), UNO_QUERY_THROW ),
589 m_xEventManager,
590 m_nCurrentElement
592 ++m_nCurrentElement;
593 return aComponent;
596 private:
597 const Reference< XIndexAccess > m_xContainer;
598 const Reference< XEventAttacherManager > m_xEventManager;
599 const sal_Int32 m_nElementCount;
600 sal_Int32 m_nCurrentElement;
604 //====================================================================
605 //= ScriptsStorage - declaration
606 //====================================================================
607 /** a helper class which encapsulates access to the storages for Java/Script, BeanShell, and Python scripts,
608 i.e. all script types which can be manipulated on storage level.
610 class ScriptsStorage
612 public:
613 ScriptsStorage( MigrationLog& _rLogger );
614 ScriptsStorage( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger );
615 ~ScriptsStorage();
617 /** determines whether the instance is valid, i.e. refers to a valid root storage
618 for reading/storing scripts
620 inline bool isValid() const { return m_xScriptsStorage.is(); }
622 /** binds the instance to a new document. Only to be called when the instance is not yet
623 bound (i.e. isValid returns <FALSE/>).
625 void bind( const Reference< XModel >& _rxDocument );
627 /// determines whether scripts of the given type are present
628 bool hasScripts( const ScriptType _eType ) const;
630 /// returns the root storage for the scripts of the given type
631 SharedStorage
632 getScriptsRoot( const ScriptType _eType ) const;
634 /** returns the names of the elements in the "Scripts" storage
636 ::std::set< ::rtl::OUString >
637 getElementNames() const;
639 /** removes the sub storage for a given script type
640 @precond
641 the respective storage is empty
642 @precond
643 the ScriptsStorage instance was opened for writing
645 void removeScriptTypeStorage( const ScriptType _eType ) const;
647 /** commits the changes at our XStorage object
649 bool commit();
651 /** removes the "Scripts" sub storage from the given document's root storage
652 @precond
653 the "Scripts" storage is empty
655 static bool
656 removeFromDocument( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger );
658 private:
659 MigrationLog& m_rLogger;
660 SharedStorage m_xScriptsStorage;
663 //====================================================================
664 //= ScriptsStorage - implementation
665 //====================================================================
666 //--------------------------------------------------------------------
667 ScriptsStorage::ScriptsStorage( MigrationLog& _rLogger )
668 :m_rLogger( _rLogger )
669 ,m_xScriptsStorage()
673 //--------------------------------------------------------------------
674 ScriptsStorage::ScriptsStorage( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
675 :m_rLogger( _rLogger )
676 ,m_xScriptsStorage()
678 bind( _rxDocument );
681 //--------------------------------------------------------------------
682 ScriptsStorage::~ScriptsStorage()
686 //--------------------------------------------------------------------
687 bool ScriptsStorage::commit()
689 return lcl_commitStorage_nothrow( m_xScriptsStorage );
692 //--------------------------------------------------------------------
693 void ScriptsStorage::bind( const Reference< XModel >& _rxDocument )
695 OSL_PRECOND( !isValid(), "ScriptsStorage:bind: did not bother, yet, to check whether this is allowed!" );
698 Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
699 Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
701 // the the "Scripts" storage exist, or if it does not (yet) exist and we are in write mode
702 // => open the storage
703 if ( ( xDocStorage->hasByName( lcl_getScriptsStorageName() )
704 && xDocStorage->isStorageElement( lcl_getScriptsStorageName() )
706 || !xDocStorage->hasByName( lcl_getScriptsStorageName() )
709 m_xScriptsStorage.set(
710 xDocStorage->openStorageElement(
711 lcl_getScriptsStorageName(), ElementModes::READWRITE
713 UNO_QUERY_THROW
717 catch( const Exception& )
719 m_rLogger.logFailure( MigrationError(
720 ERR_BIND_SCRIPT_STORAGE_FAILED,
721 ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
722 ::cppu::getCaughtException()
723 ) );
727 //--------------------------------------------------------------------
728 bool ScriptsStorage::hasScripts( const ScriptType _eType ) const
730 OSL_PRECOND( isValid(), "ScriptsStorage::hasScripts: illegal call!" );
731 if ( !isValid() )
732 return false;
734 const ::rtl::OUString& rSubStorageName( lcl_getScriptsSubStorageName( _eType ) );
735 return m_xScriptsStorage->hasByName( rSubStorageName )
736 && m_xScriptsStorage->isStorageElement( rSubStorageName );
739 //--------------------------------------------------------------------
740 SharedStorage ScriptsStorage::getScriptsRoot( const ScriptType _eType ) const
742 SharedStorage xStorage;
743 if ( isValid() )
745 xStorage.reset( m_xScriptsStorage->openStorageElement(
746 lcl_getScriptsSubStorageName( _eType ), ElementModes::READWRITE
747 ) );
749 return xStorage;
752 //--------------------------------------------------------------------
753 ::std::set< ::rtl::OUString > ScriptsStorage::getElementNames() const
755 Sequence< ::rtl::OUString > aElementNames;
756 if ( isValid() )
757 aElementNames = m_xScriptsStorage->getElementNames();
759 ::std::set< ::rtl::OUString > aNames;
760 ::std::copy(
761 aElementNames.getConstArray(),
762 aElementNames.getConstArray() + aElementNames.getLength(),
763 ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aNames, aNames.end() )
765 return aNames;
768 //--------------------------------------------------------------------
769 void ScriptsStorage::removeScriptTypeStorage( const ScriptType _eType ) const
771 ::rtl::OUString sSubStorageName( lcl_getScriptsSubStorageName( _eType ) );
772 if ( m_xScriptsStorage->hasByName( sSubStorageName ) )
773 m_xScriptsStorage->removeElement( sSubStorageName );
776 //--------------------------------------------------------------------
777 bool ScriptsStorage::removeFromDocument( const Reference< XModel >& _rxDocument, MigrationLog& _rLogger )
781 Reference< XStorageBasedDocument > xStorageDoc( _rxDocument, UNO_QUERY_THROW );
782 Reference< XStorage > xDocStorage( xStorageDoc->getDocumentStorage(), UNO_QUERY_THROW );
783 xDocStorage->removeElement( lcl_getScriptsStorageName() );
785 catch( const Exception& )
787 _rLogger.logFailure( MigrationError(
788 ERR_REMOVE_SCRIPTS_STORAGE_FAILED,
789 ::comphelper::DocumentInfo::getDocumentTitle( _rxDocument ),
790 ::cppu::getCaughtException()
791 ) ) ;
792 return false;
794 return true;
797 //====================================================================
798 //= ProgressDelegator
799 //====================================================================
800 class ProgressDelegator : public IProgressConsumer
802 public:
803 ProgressDelegator( IMigrationProgress& _rDelegator,
804 const ::rtl::OUString& _rObjectName,
805 const ::rtl::OUString& _rAction
807 :m_rDelegator( _rDelegator )
808 ,m_sObjectName( _rObjectName )
809 ,m_sAction( _rAction )
812 virtual ~ProgressDelegator()
816 // IProgressConsumer
817 virtual void start( sal_uInt32 _nRange )
819 m_rDelegator.startObject( m_sObjectName, m_sAction, _nRange );
821 virtual void advance( sal_uInt32 _nValue )
823 m_rDelegator.setObjectProgressValue( _nValue );
825 virtual void end()
827 m_rDelegator.endObject();
830 private:
831 IMigrationProgress& m_rDelegator;
832 ::rtl::OUString m_sObjectName;
833 ::rtl::OUString m_sAction;
836 //====================================================================
837 //= PhaseGuard
838 //====================================================================
839 class PhaseGuard
841 public:
842 PhaseGuard( ProgressMixer& _rMixer )
843 :m_rMixer( _rMixer )
847 PhaseGuard( ProgressMixer& _rMixer, const PhaseID _nID, const sal_uInt32 _nPhaseRange )
848 :m_rMixer( _rMixer )
850 start( _nID, _nPhaseRange );
853 ~PhaseGuard()
855 m_rMixer.endPhase();
858 void start( const PhaseID _nID, const sal_uInt32 _nPhaseRange )
860 m_rMixer.startPhase( _nID, _nPhaseRange );
863 private:
864 ProgressMixer& m_rMixer;
867 //====================================================================
868 //= MigrationEngine_Impl - declaration
869 //====================================================================
870 class MigrationEngine_Impl
872 public:
873 MigrationEngine_Impl(
874 const ::comphelper::ComponentContext& _rContext,
875 const Reference< XOfficeDatabaseDocument >& _rxDocument,
876 IMigrationProgress& _rProgress,
877 MigrationLog& _rLogger
879 ~MigrationEngine_Impl();
881 inline size_t getFormCount() const { return m_nFormCount; }
882 inline size_t getReportCount()const { return m_nReportCount; }
883 bool migrateAll();
885 private:
886 ::comphelper::ComponentContext m_aContext;
887 const Reference< XOfficeDatabaseDocument > m_xDocument;
888 const Reference< XModel > m_xDocumentModel;
889 IMigrationProgress& m_rProgress;
890 MigrationLog& m_rLogger;
891 mutable DocumentID m_nCurrentDocumentID;
892 SubDocuments m_aSubDocs;
893 size_t m_nFormCount;
894 size_t m_nReportCount;
896 private:
897 /** collects a description of all sub documents of our database document
899 @return
900 <TRUE/> if and only if collecting the documents was successful
902 bool impl_collectSubDocuments_nothrow();
904 /** migrates the macros/scripts of the given sub document
906 bool impl_handleDocument_nothrow( const SubDocument& _rDocument ) const;
908 /** checks the structure of the 'Scripts' folder of a sub document
909 for unknown elements
911 @return
912 <TRUE/> if and only if the 'Scripts' folder contains known elements only.
914 bool impl_checkScriptStorageStructure_nothrow( const SubDocument& _rDocument ) const;
916 /** migrates the scripts of the given "storage-based" script type
918 bool impl_migrateScriptStorage_nothrow(
919 const SubDocument& _rDocument,
920 const ScriptType _eScriptType,
921 ProgressMixer& _rProgress,
922 const PhaseID _nPhaseID
923 ) const;
925 /** migrates the content of the given "container based" libraries (Basic/Dialogs)
927 bool impl_migrateContainerLibraries_nothrow(
928 const SubDocument& _rDocument,
929 const ScriptType _eScriptType,
930 ProgressMixer& _rProgress,
931 const PhaseID _nPhaseID
932 ) const;
934 /** adjusts the events for the given dialog/element, taking into account the new names
935 of the moved libraries
937 void impl_adjustDialogElementEvents_throw(
938 const Reference< XInterface >& _rxElement
939 ) const;
941 /** adjusts the events in the given dialog, and its controls, taking into account the new names
942 of the moved libraries
944 bool impl_adjustDialogEvents_nothrow(
945 Any& _inout_rDialogLibraryElement,
946 const ::rtl::OUString& _rDocName,
947 const ::rtl::OUString& _rDialogLibName,
948 const ::rtl::OUString& _rDialogName
949 ) const;
951 /** adjust the document-events which refer to macros/scripts in the document, taking into
952 account the new names of the moved libraries
954 bool impl_adjustDocumentEvents_nothrow(
955 const SubDocument& _rDocument
956 ) const;
958 /** adjusts the script references bound to form component events
960 bool impl_adjustFormComponentEvents_nothrow(
961 const SubDocument& _rDocument
962 ) const;
964 /** adjusts the script references for the elements of the given form component container
966 void impl_adjustFormComponentEvents_throw(
967 const Reference< XIndexAccess >& _rxComponentContainer
968 ) const;
970 /** adjusts the library name in the given script URL, so that it reflects
971 the new name of the library
973 @return <TRUE/>
974 if and only if adjustments to the script code have been made
976 bool impl_adjustScriptLibrary_nothrow(
977 const ::rtl::OUString& _rScriptType,
978 ::rtl::OUString& _inout_rScriptCode
979 ) const;
981 bool impl_adjustScriptLibrary_nothrow( Any& _inout_rScriptDescriptor ) const;
982 bool impl_adjustScriptLibrary_nothrow( ScriptEventDescriptor& _inout_rScriptEvent ) const;
984 /** asks the user for a password for the given library, and unprotects the library
986 @return <TRUE/>
987 if and only if the library could be successfully unprotected
989 bool impl_unprotectPasswordLibrary_throw(
990 const Reference< XLibraryContainerPassword >& _rxPasswordManager,
991 const ScriptType _eScriptType,
992 const ::rtl::OUString& _rLibraryName
993 ) const;
996 //====================================================================
997 //= MigrationEngine_Impl - implementation
998 //====================================================================
999 //--------------------------------------------------------------------
1000 MigrationEngine_Impl::MigrationEngine_Impl( const ::comphelper::ComponentContext& _rContext,
1001 const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress, MigrationLog& _rLogger )
1002 :m_aContext( _rContext )
1003 ,m_xDocument( _rxDocument )
1004 ,m_xDocumentModel( _rxDocument, UNO_QUERY_THROW )
1005 ,m_rProgress( _rProgress )
1006 ,m_rLogger( _rLogger )
1007 ,m_nCurrentDocumentID( - 1 )
1008 ,m_aSubDocs()
1009 ,m_nFormCount( 0 )
1010 ,m_nReportCount( 0 )
1012 OSL_VERIFY( impl_collectSubDocuments_nothrow() );
1015 //--------------------------------------------------------------------
1016 MigrationEngine_Impl::~MigrationEngine_Impl()
1020 //--------------------------------------------------------------------
1021 bool MigrationEngine_Impl::migrateAll()
1023 if ( m_aSubDocs.empty() )
1025 OSL_ENSURE( false, "MigrationEngine_Impl::migrateAll: no forms/reports found!" );
1026 // The whole migration wizard is not expected to be called when there are no forms/reports
1027 // with macros, not to mention when there are no forms/reports at all.
1028 return false;
1031 // initialize global progress
1032 sal_Int32 nOverallRange( m_aSubDocs.size() );
1033 String sProgressSkeleton = String( MacroMigrationResId( STR_OVERALL_PROGRESS ) );
1034 sProgressSkeleton.SearchAndReplaceAscii( "$overall$", String::CreateFromInt32( nOverallRange ) );
1036 m_rProgress.start( nOverallRange );
1038 for ( SubDocuments::const_iterator doc = m_aSubDocs.begin();
1039 doc != m_aSubDocs.end();
1040 ++doc
1043 sal_Int32 nOverallProgressValue( doc - m_aSubDocs.begin() + 1 );
1044 // update overall progress text
1045 ::rtl::OUString sOverallProgress( sProgressSkeleton );
1046 ::comphelper::string::searchAndReplaceAsciiI( sOverallProgress, "$current$", ::rtl::OUString::valueOf( nOverallProgressValue ) );
1047 m_rProgress.setOverallProgressText( sOverallProgress );
1049 // migrate document
1050 if ( !impl_handleDocument_nothrow( *doc ) )
1051 return false;
1053 // update overall progress vallue
1054 m_rProgress.setOverallProgressValue( nOverallProgressValue );
1057 // commit the root storage of the database document, for all changes made so far to take effect
1058 if ( !lcl_commitDocumentStorage_nothrow( m_xDocumentModel, m_rLogger ) )
1059 return false;
1061 // save the document
1062 if ( !lcl_storeDocument_nothrow( m_xDocumentModel, m_rLogger ) )
1063 return false;
1065 return true;
1068 //--------------------------------------------------------------------
1069 namespace
1071 void lcl_collectHierarchicalElementNames_throw(
1072 const Reference< XNameAccess >& _rxContainer, const ::rtl::OUString& _rContainerLoc,
1073 SubDocuments& _out_rDocs, const SubDocumentType _eType, size_t& _io_counter )
1075 const ::rtl::OUString sHierarhicalBase(
1076 _rContainerLoc.getLength() ? ::rtl::OUStringBuffer( _rContainerLoc ).appendAscii( "/" ).makeStringAndClear()
1077 : ::rtl::OUString() );
1079 Sequence< ::rtl::OUString > aElementNames( _rxContainer->getElementNames() );
1080 for ( const ::rtl::OUString* elementName = aElementNames.getConstArray();
1081 elementName != aElementNames.getConstArray() + aElementNames.getLength();
1082 ++elementName
1085 Any aElement( _rxContainer->getByName( *elementName ) );
1086 ::rtl::OUString sElementName( ::rtl::OUStringBuffer( sHierarhicalBase ).append( *elementName ) );
1088 Reference< XNameAccess > xSubContainer( aElement, UNO_QUERY );
1089 if ( xSubContainer.is() )
1091 lcl_collectHierarchicalElementNames_throw( xSubContainer, sElementName, _out_rDocs, _eType, _io_counter );
1093 else
1095 Reference< XCommandProcessor > xCommandProcessor( aElement, UNO_QUERY );
1096 OSL_ENSURE( xCommandProcessor.is(), "lcl_collectHierarchicalElementNames_throw: no container, and no comand processor? What *is* it, then?!" );
1097 if ( xCommandProcessor.is() )
1099 _out_rDocs.push_back( SubDocument( xCommandProcessor, sElementName, _eType, ++_io_counter ) );
1106 //--------------------------------------------------------------------
1107 bool MigrationEngine_Impl::impl_collectSubDocuments_nothrow()
1109 OSL_PRECOND( m_xDocument.is(), "MigrationEngine_Impl::impl_collectSubDocuments_nothrow: invalid document!" );
1110 if ( !m_xDocument.is() )
1111 return false;
1115 Reference< XNameAccess > xDocContainer( m_xDocument->getFormDocuments(), UNO_SET_THROW );
1116 m_nFormCount = 0;
1117 lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eForm, m_nFormCount );
1119 xDocContainer.set( m_xDocument->getReportDocuments(), UNO_SET_THROW );
1120 m_nReportCount = 0;
1121 lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eReport, m_nReportCount );
1123 catch( const Exception& )
1125 m_rLogger.logFailure( MigrationError(
1126 ERR_COLLECTING_DOCUMENTS_FAILED,
1127 ::cppu::getCaughtException()
1128 ) );
1129 return false;
1131 return true;
1134 //--------------------------------------------------------------------
1135 bool MigrationEngine_Impl::impl_handleDocument_nothrow( const SubDocument& _rDocument ) const
1137 OSL_ENSURE( m_nCurrentDocumentID == -1,
1138 "MigrationEngine_Impl::impl_handleDocument_nothrow: there already is a current document!");
1139 m_nCurrentDocumentID = m_rLogger.startedDocument( _rDocument.eType, _rDocument.sHierarchicalName );
1141 // start the progress
1142 ::rtl::OUString sObjectName( lcl_getSubDocumentDescription( _rDocument ) );
1143 m_rProgress.startObject( sObjectName, ::rtl::OUString(), DEFAULT_DOC_PROGRESS_RANGE );
1145 // -----------------
1146 // load the document
1147 ::rtl::Reference< ProgressCapture > pStatusIndicator( new ProgressCapture( sObjectName, m_rProgress ) );
1148 SubDocument aSubDocument( _rDocument );
1149 OpenDocResult eResult = lcl_loadSubDocument_nothrow( aSubDocument, pStatusIndicator.get(), m_rLogger );
1150 if ( eResult != eOpenedDoc )
1152 pStatusIndicator->dispose();
1153 m_rProgress.endObject();
1154 m_rLogger.finishedDocument( m_nCurrentDocumentID );
1155 m_nCurrentDocumentID = -1;
1156 return ( eResult == eIgnoreDoc );
1159 // -----------------
1160 // migrate the libraries
1161 ProgressDelegator aDelegator( m_rProgress, sObjectName, String( MacroMigrationResId( STR_MIGRATING_LIBS ) ) );
1162 ProgressMixer aProgressMixer( aDelegator );
1163 aProgressMixer.registerPhase( PHASE_JAVASCRIPT, 1 );
1164 aProgressMixer.registerPhase( PHASE_BEANSHELL, 1 );
1165 aProgressMixer.registerPhase( PHASE_PYTHON, 1 );
1166 aProgressMixer.registerPhase( PHASE_JAVA, 1 );
1167 aProgressMixer.registerPhase( PHASE_BASIC, 5 );
1168 // more weight than then others, assuming that usually, there are much more Basic macros than any other scripts
1169 aProgressMixer.registerPhase( PHASE_DIALOGS, 1 );
1171 bool bSuccess = impl_checkScriptStorageStructure_nothrow( aSubDocument );
1173 // migrate storage-based script libraries (which can be handled by mere storage operations)
1174 bSuccess = bSuccess
1175 && impl_migrateScriptStorage_nothrow( aSubDocument, eJavaScript, aProgressMixer, PHASE_JAVASCRIPT )
1176 && impl_migrateScriptStorage_nothrow( aSubDocument, eBeanShell, aProgressMixer, PHASE_BEANSHELL )
1177 && impl_migrateScriptStorage_nothrow( aSubDocument, ePython, aProgressMixer, PHASE_PYTHON )
1178 && impl_migrateScriptStorage_nothrow( aSubDocument, eJava, aProgressMixer, PHASE_JAVA );
1180 // migrate Basic and dialog libraries
1181 bSuccess = bSuccess
1182 && impl_migrateContainerLibraries_nothrow( aSubDocument, eBasic, aProgressMixer, PHASE_BASIC )
1183 && impl_migrateContainerLibraries_nothrow( aSubDocument, eDialog, aProgressMixer, PHASE_DIALOGS );
1184 // order matters: First Basic scripts, then dialogs. So we can adjust references from the latter
1185 // to the former
1187 // adjust the events in the document
1188 // (note that errors are ignored here - failure to convert a script reference
1189 // is not considered a critical error)
1190 if ( bSuccess )
1192 impl_adjustDocumentEvents_nothrow( aSubDocument );
1193 impl_adjustFormComponentEvents_nothrow( aSubDocument );
1196 // -----------------
1197 // clean up
1198 // store the sub document, including removal of the (now obsolete) "Scripts" sub folder
1199 if ( m_rLogger.movedAnyLibrary( m_nCurrentDocumentID ) )
1201 bSuccess = bSuccess
1202 && ScriptsStorage::removeFromDocument( aSubDocument.xDocument, m_rLogger )
1203 && lcl_commitDocumentStorage_nothrow( aSubDocument.xDocument, m_rLogger )
1204 && lcl_storeEmbeddedDocument_nothrow( aSubDocument );
1207 // unload in any case, even if we were not successful
1208 bSuccess = lcl_unloadSubDocument_nothrow( aSubDocument, m_rLogger )
1209 && bSuccess;
1211 pStatusIndicator->dispose();
1213 // end the progress, just in case the ProgressCapture didn't receive the XStatusIndicator::end event
1214 m_rProgress.endObject();
1216 m_rLogger.finishedDocument( m_nCurrentDocumentID );
1217 m_nCurrentDocumentID = -1;
1218 return bSuccess;
1221 //--------------------------------------------------------------------
1222 namespace
1224 static ::rtl::OUString lcl_createTargetLibName( const SubDocument& _rDocument,
1225 const ::rtl::OUString& _rSourceLibName, const Reference< XNameAccess >& _rxTargetContainer )
1227 // The new library name is composed from the prefix, the base name, and the old library name.
1228 const ::rtl::OUString sPrefix( ::rtl::OUString::createFromAscii( _rDocument.eType == eForm ? "Form_" : "Report_" ) );
1230 ::rtl::OUString sBaseName( _rDocument.sHierarchicalName.copy(
1231 _rDocument.sHierarchicalName.lastIndexOf( '/' ) + 1 ) );
1232 // Normalize this name. In our current storage implementation (and script containers in a document
1233 // are finally mapped to sub storages of the document storage), not all characters are allowed.
1234 // The bug requesting to change this is #i95409#.
1235 // Unfortunately, the storage implementation does not complain if you use invalid characters/names, but instead
1236 // it silently accepts them, and produces garbage in the file (#i95408).
1237 // So, until especially the former is fixed, we need to strip the name from all invalid characters.
1238 // #i95865# / 2008-11-06 / frank.schoenheit@sun.com
1240 // The general idea is to replace invalid characters with '_'. However, since "valid" essentially means
1241 // ASCII only, this implies that for a lot of languages, we would simply replace everything with '_',
1242 // which of course is not desired.
1243 // So, we use a heuristics: If the name contains at most 3 invalid characters, and as many valid as invalid
1244 // characters, then we use the replacement. Otherwise, we just use a unambiguous number for the sub document.
1245 sal_Int32 nValid=0, nInvalid=0;
1246 const sal_Unicode* pBaseName = sBaseName.getStr();
1247 const sal_Int32 nBaseNameLen = sBaseName.getLength();
1248 for ( sal_Int32 i=0; i<nBaseNameLen; ++i )
1250 if ( ::comphelper::OStorageHelper::IsValidZipEntryFileName( pBaseName + i, 1, sal_False ) )
1251 ++nValid;
1252 else
1253 ++nInvalid;
1255 if ( ( nInvalid <= 3 ) && ( nInvalid * 2 <= nValid ) )
1256 { // not "too many" invalid => replace them
1257 ::rtl::OUStringBuffer aReplacement;
1258 aReplacement.ensureCapacity( nBaseNameLen );
1259 aReplacement.append( sBaseName );
1260 const sal_Unicode* pReplacement = aReplacement.getStr();
1261 for ( sal_Int32 i=0; i<nBaseNameLen; ++i )
1263 if ( !::comphelper::OStorageHelper::IsValidZipEntryFileName( pReplacement + i, 1, sal_False ) )
1264 aReplacement.setCharAt( i, '_' );
1266 sBaseName = aReplacement.makeStringAndClear();
1268 ::rtl::OUStringBuffer aNewLibNameAttempt;
1269 aNewLibNameAttempt.append( sPrefix );
1270 aNewLibNameAttempt.append( sBaseName );
1271 aNewLibNameAttempt.appendAscii( "_" );
1272 aNewLibNameAttempt.append( _rSourceLibName );
1273 ::rtl::OUString sTargetName( aNewLibNameAttempt.makeStringAndClear() );
1274 if ( !_rxTargetContainer->hasByName( sTargetName ) )
1275 return sTargetName;
1278 // "too many" invalid characters, or the name composed with the base name was already used.
1279 // (The latter is valid, since there can be multiple sub documents with the same base name,
1280 // in different levels in the hierarchy.)
1281 // In this case, just use the umambiguous sub document number.
1282 ::rtl::OUStringBuffer aNewLibName;
1283 aNewLibName.append( sPrefix );
1284 aNewLibName.append( ::rtl::OUString::valueOf( sal_Int64( _rDocument.nNumber ) ) );
1285 aNewLibName.appendAscii( "_" );
1286 aNewLibName.append( _rSourceLibName );
1287 return aNewLibName.makeStringAndClear();
1291 //--------------------------------------------------------------------
1292 bool MigrationEngine_Impl::impl_checkScriptStorageStructure_nothrow( const SubDocument& _rDocument ) const
1294 OSL_PRECOND( _rDocument.xDocument.is(), "MigrationEngine_Impl::impl_checkScriptStorageStructure_nothrow: invalid document!" );
1295 if ( !_rDocument.xDocument.is() )
1296 return false;
1300 // the root storage of the document whose scripts are to be migrated
1301 ScriptsStorage aDocStorage( _rDocument.xDocument, m_rLogger );
1302 if ( !aDocStorage.isValid() )
1303 { // no scripts at all, or no scripts of the given type
1304 return !m_rLogger.hadFailure();
1306 ::std::set< ::rtl::OUString > aElementNames( aDocStorage.getElementNames() );
1308 ScriptType aKnownStorageBasedTypes[] = {
1309 eBeanShell, eJavaScript, ePython, eJava
1311 for ( size_t i=0; i<sizeof( aKnownStorageBasedTypes ) / sizeof( aKnownStorageBasedTypes[0] ); ++i )
1312 aElementNames.erase( lcl_getScriptsSubStorageName( aKnownStorageBasedTypes[i] ) );
1314 if ( !aElementNames.empty() )
1316 m_rLogger.logFailure( MigrationError(
1317 ERR_UNKNOWN_SCRIPT_FOLDER,
1318 lcl_getSubDocumentDescription( _rDocument ),
1319 *aElementNames.begin()
1320 ) );
1321 return false;
1324 catch( const Exception& )
1326 m_rLogger.logFailure( MigrationError(
1327 ERR_EXAMINING_SCRIPTS_FOLDER_FAILED,
1328 lcl_getSubDocumentDescription( _rDocument ),
1329 ::cppu::getCaughtException()
1330 ) );
1331 return false;
1333 return true;
1336 //--------------------------------------------------------------------
1337 bool MigrationEngine_Impl::impl_migrateScriptStorage_nothrow( const SubDocument& _rDocument,
1338 const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const
1340 OSL_PRECOND( _rDocument.xDocument.is(), "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: invalid document!" );
1341 if ( !_rDocument.xDocument.is() )
1342 return false;
1344 ScriptsStorage aDatabaseScripts( m_rLogger );
1345 // the scripts of our complete database document - created on demand only
1346 SharedStorage xTargetStorage;
1347 // the target for moving the scripts storages - created on demand only
1349 PhaseGuard aPhase( _rProgress );
1350 bool bSuccess = false;
1351 Any aException;
1354 // the root storage of the document whose scripts are to be migrated
1355 ScriptsStorage aDocStorage( _rDocument.xDocument, m_rLogger );
1356 if ( !aDocStorage.isValid()
1357 || !aDocStorage.hasScripts( _eScriptType )
1360 // no scripts at all, or no scripts of the given type
1361 _rProgress.startPhase( _nPhaseID, 1 );
1362 _rProgress.endPhase();
1363 return !m_rLogger.hadFailure();
1366 SharedStorage xScriptsRoot( aDocStorage.getScriptsRoot( _eScriptType ) );
1367 if ( !xScriptsRoot.is() )
1368 throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "internal error" ) ), NULL );
1370 // loop through the script libraries
1371 Sequence< ::rtl::OUString > aStorageElements( xScriptsRoot->getElementNames() );
1372 aPhase.start( _nPhaseID, aStorageElements.getLength() );
1374 for ( const ::rtl::OUString* element = aStorageElements.getConstArray();
1375 element != aStorageElements.getConstArray() + aStorageElements.getLength();
1376 ++element
1379 bool bIsScriptLibrary = xScriptsRoot->isStorageElement( *element );
1380 OSL_ENSURE( bIsScriptLibrary,
1381 "MigrationEngine_Impl::impl_migrateScriptStorage_nothrow: warning: unknown scripts storage structure!" );
1382 // we cannot handle this. We would need to copy this stream to the respective scripts storage
1383 // of the database document, but we cannot guarantee that the name is not used, yet, and we cannot
1384 // simply rename the thing.
1385 if ( !bIsScriptLibrary )
1387 m_rLogger.logFailure( MigrationError(
1388 ERR_UNEXPECTED_LIBSTORAGE_ELEMENT,
1389 lcl_getSubDocumentDescription( _rDocument ),
1390 getScriptTypeDisplayName( _eScriptType ),
1391 *element
1392 ) );
1393 return false;
1396 // ensure we have access to the DBDoc's scripts storage
1397 if ( !aDatabaseScripts.isValid() )
1398 { // not needed 'til now
1399 aDatabaseScripts.bind( m_xDocumentModel );
1400 if ( aDatabaseScripts.isValid() )
1401 xTargetStorage = aDatabaseScripts.getScriptsRoot( _eScriptType );
1403 if ( !xTargetStorage.is() )
1405 m_rLogger.logFailure( MigrationError(
1406 ERR_CREATING_DBDOC_SCRIPT_STORAGE_FAILED,
1407 getScriptTypeDisplayName( _eScriptType )
1408 ) );
1409 return false;
1413 // move the library to the DBDoc's scripts library, under the new name
1414 ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *element, xTargetStorage.getTyped().get() ) );
1415 xScriptsRoot->moveElementTo( *element, xTargetStorage, sNewLibName );
1417 // log the fact that we moved the library
1418 m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *element, sNewLibName );
1420 // progress
1421 _rProgress.advancePhase( element - aStorageElements.getConstArray() );
1424 // commit the storages, so the changes we made persist
1425 if ( !lcl_commitStorage_nothrow( xScriptsRoot )
1426 || ( xTargetStorage.is() && !lcl_commitStorage_nothrow( xTargetStorage ) )
1429 m_rLogger.logFailure( MigrationError(
1430 ERR_COMMITTING_SCRIPT_STORAGES_FAILED,
1431 getScriptTypeDisplayName( _eScriptType ),
1432 lcl_getSubDocumentDescription( _rDocument )
1433 ) );
1434 return false;
1437 // now that the concrete scripts storage does not have any elements anymore,
1438 // remove it
1439 xScriptsRoot.reset( NULL ); // need to reset the storage to be allowed to remove it
1440 aDocStorage.removeScriptTypeStorage( _eScriptType );
1442 // done so far
1443 bSuccess = aDocStorage.commit()
1444 && aDatabaseScripts.commit();
1446 catch( const Exception& )
1448 aException = ::cppu::getCaughtException();
1449 bSuccess = false;
1452 // log the error, if any
1453 if ( !bSuccess )
1455 m_rLogger.logFailure( MigrationError(
1456 ERR_GENERAL_SCRIPT_MIGRATION_FAILURE,
1457 getScriptTypeDisplayName( _eScriptType ),
1458 lcl_getSubDocumentDescription( _rDocument ),
1459 aException
1460 ) );
1463 return bSuccess;
1466 //--------------------------------------------------------------------
1467 bool MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow( const SubDocument& _rDocument,
1468 const ScriptType _eScriptType, ProgressMixer& _rProgress, const PhaseID _nPhaseID ) const
1470 OSL_PRECOND( ( _eScriptType == eBasic ) || ( _eScriptType == eDialog ),
1471 "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: illegal script type!" );
1473 bool bSuccess = false;
1474 PhaseGuard aPhase( _rProgress );
1475 Any aException;
1476 do // artificial loop for flow control only
1480 // access library container of the sub document
1481 Reference< XEmbeddedScripts > xSubDocScripts( _rDocument.xDocument, UNO_QUERY );
1482 if ( !xSubDocScripts.is() )
1483 { // no script support in the sub document -> nothing to migrate
1484 // (though ... this is suspicious, at least ...)
1485 bSuccess = true;
1486 break;
1489 Reference< XStorageBasedLibraryContainer > xSourceLibraries(
1490 _eScriptType == eBasic ? xSubDocScripts->getBasicLibraries() : xSubDocScripts->getDialogLibraries(),
1491 UNO_QUERY_THROW
1493 Reference< XLibraryContainerPassword > xSourcePasswords( xSourceLibraries, UNO_QUERY );
1494 OSL_ENSURE( xSourcePasswords.is(),
1495 "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: suspicious: no password management for the source libraries!" );
1497 Sequence< ::rtl::OUString > aSourceLibNames( xSourceLibraries->getElementNames() );
1498 aPhase.start( _nPhaseID, aSourceLibNames.getLength() );
1500 if ( !xSourceLibraries->hasElements() )
1502 bSuccess = true;
1503 break;
1506 // create library containers for the document - those will be the target for the migration
1507 Reference< XStorageBasedDocument > xStorageDoc( m_xDocument, UNO_QUERY_THROW );
1508 Reference< XStorageBasedLibraryContainer > xTargetLibraries;
1509 if ( _eScriptType == eBasic )
1511 xTargetLibraries.set( DocumentScriptLibraryContainer::create(
1512 m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW );
1514 else
1516 xTargetLibraries.set( DocumentDialogLibraryContainer::create(
1517 m_aContext.getUNOContext(), xStorageDoc ), UNO_QUERY_THROW );
1520 // copy all libs to the target, with potentially renaming them
1521 const ::rtl::OUString* pSourceLibBegin = aSourceLibNames.getConstArray();
1522 const ::rtl::OUString* pSourceLibEnd = pSourceLibBegin + aSourceLibNames.getLength();
1523 for ( const ::rtl::OUString* pSourceLibName = pSourceLibBegin;
1524 pSourceLibName != pSourceLibEnd;
1525 ++pSourceLibName
1528 // if the library is password-protected, ask the user to unprotect it
1529 if ( xSourcePasswords.is()
1530 && xSourcePasswords->isLibraryPasswordProtected( *pSourceLibName )
1531 && !xSourcePasswords->isLibraryPasswordVerified( *pSourceLibName )
1534 if ( !impl_unprotectPasswordLibrary_throw( xSourcePasswords, _eScriptType, *pSourceLibName ) )
1536 m_rLogger.logFailure( MigrationError(
1537 ERR_PASSWORD_VERIFICATION_FAILED,
1538 _rDocument.sHierarchicalName,
1539 getScriptTypeDisplayName( _eScriptType ),
1540 *pSourceLibName
1541 ) );
1542 return false;
1546 ::rtl::OUString sNewLibName( lcl_createTargetLibName( _rDocument, *pSourceLibName, xTargetLibraries.get() ) );
1548 if ( xSourceLibraries->isLibraryLink( *pSourceLibName ) )
1550 // just re-create the link in the target library
1551 xTargetLibraries->createLibraryLink(
1552 sNewLibName,
1553 xSourceLibraries->getLibraryLinkURL( *pSourceLibName ),
1554 xSourceLibraries->isLibraryReadOnly( *pSourceLibName )
1557 else
1559 if ( !xSourceLibraries->isLibraryLoaded( *pSourceLibName ) )
1560 xSourceLibraries->loadLibrary( *pSourceLibName );
1562 // copy the content of this particular libary
1563 Reference< XNameAccess > xSourceLib( xSourceLibraries->getByName( *pSourceLibName ), UNO_QUERY_THROW );
1564 Reference< XNameContainer > xTargetLib( xTargetLibraries->createLibrary( sNewLibName ), UNO_QUERY_THROW );
1566 Sequence< ::rtl::OUString > aLibElementNames( xSourceLib->getElementNames() );
1567 for ( const ::rtl::OUString* pSourceElementName = aLibElementNames.getConstArray();
1568 pSourceElementName != aLibElementNames.getConstArray() + aLibElementNames.getLength();
1569 ++pSourceElementName
1572 Any aElement = xSourceLib->getByName( *pSourceElementName );
1573 OSL_ENSURE( aElement.hasValue(),
1574 "MigrationEngine_Impl::impl_migrateContainerLibraries_nothrow: invalid (empty) lib element!" );
1576 // if this is a dialog, adjust the references to scripts
1577 if ( _eScriptType == eDialog )
1579 impl_adjustDialogEvents_nothrow( aElement, lcl_getSubDocumentDescription( _rDocument ),
1580 *pSourceLibName, *pSourceElementName );
1583 xTargetLib->insertByName( *pSourceElementName, aElement );
1586 // transfer the read-only flag
1587 xTargetLibraries->setLibraryReadOnly(
1588 sNewLibName, xSourceLibraries->isLibraryReadOnly( *pSourceLibName ) );
1591 // remove the source lib
1592 xSourceLibraries->removeLibrary( *pSourceLibName );
1594 // tell the logger
1595 m_rLogger.movedLibrary( m_nCurrentDocumentID, _eScriptType, *pSourceLibName, sNewLibName );
1597 // tell the progress
1598 _rProgress.advancePhase( pSourceLibName - pSourceLibBegin );
1601 // clean up
1602 xSourceLibraries->storeLibraries();
1604 xTargetLibraries->storeLibraries();
1605 Reference< XStorage > xTargetRoot( xTargetLibraries->getRootLocation(), UNO_QUERY_THROW );
1606 bSuccess = lcl_commitStorage_nothrow( xTargetRoot );
1608 catch( const Exception& )
1610 aException = ::cppu::getCaughtException();
1611 bSuccess = false;
1613 } while ( false );
1615 // log the error, if any
1616 if ( !bSuccess )
1618 m_rLogger.logFailure( MigrationError(
1619 ERR_GENERAL_MACRO_MIGRATION_FAILURE,
1620 lcl_getSubDocumentDescription( _rDocument ),
1621 aException
1622 ) );
1625 return bSuccess;
1628 //--------------------------------------------------------------------
1629 bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( const ::rtl::OUString& _rScriptType,
1630 ::rtl::OUString& _inout_rScriptCode ) const
1632 OSL_PRECOND( _inout_rScriptCode.getLength(), "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: invalid script!" );
1633 if ( !_inout_rScriptCode.getLength() )
1634 return false;
1636 bool bSuccess = false;
1637 Any aException;
1640 if ( !_rScriptType.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Script" ) )
1641 || !_rScriptType.getLength()
1644 OSL_ENSURE( false,
1645 "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: no or unknown script type!" );
1646 m_rLogger.logRecoverable( MigrationError(
1647 ERR_UNKNOWN_SCRIPT_TYPE,
1648 _rScriptType
1649 ) );
1650 return false;
1653 // analyze the script URI
1654 Reference< XUriReferenceFactory > xUriRefFac = UriReferenceFactory::create( m_aContext.getUNOContext() );
1655 Reference< XVndSunStarScriptUrlReference > xUri( xUriRefFac->parse( _inout_rScriptCode ), UNO_QUERY_THROW );
1657 ::rtl::OUString sScriptLanguage = xUri->getParameter(
1658 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "language" ) ) );
1659 ScriptType eScriptType = eBasic;
1660 if ( !lcl_getScriptTypeFromLanguage( sScriptLanguage, eScriptType ) )
1662 OSL_ENSURE( false,
1663 "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: unknown script language!" );
1664 m_rLogger.logRecoverable( MigrationError(
1665 ERR_UNKNOWN_SCRIPT_LANGUAGE,
1666 sScriptLanguage
1667 ) );
1668 return false;
1671 ::rtl::OUString sLocation = xUri->getParameter(
1672 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "location" ) ) );
1673 if ( !sLocation.equalsAscii( "document" ) )
1675 // only document libraries must be migrated, of course
1676 return false;
1679 ::rtl::OUString sScriptName = xUri->getName();
1680 sal_Int32 nLibModuleSeparator = sScriptName.indexOf( '.' );
1681 if ( nLibModuleSeparator < 0 )
1683 OSL_ENSURE( false,
1684 "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: invalid/unknown location format!" );
1685 m_rLogger.logRecoverable( MigrationError(
1686 ERR_UNKNOWN_SCRIPT_NAME_FORMAT,
1687 sScriptName
1688 ) );
1689 return false;
1692 // replace the library name
1693 ::rtl::OUString sLibrary = sScriptName.copy( 0, nLibModuleSeparator );
1694 ::rtl::OUString sNewLibName = m_rLogger.getNewLibraryName(
1695 m_nCurrentDocumentID, eScriptType, sLibrary );
1696 OSL_ENSURE( sLibrary != sNewLibName,
1697 "MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow: a library which has not been migrated?" );
1699 ::rtl::OUStringBuffer aNewLocation;
1700 aNewLocation.append( sNewLibName );
1701 aNewLocation.append( sScriptName.copy( nLibModuleSeparator ) );
1702 xUri->setName( aNewLocation.makeStringAndClear() );
1704 // update the new script URL
1705 _inout_rScriptCode = xUri->getUriReference();
1706 bSuccess = true;
1708 catch( const Exception& )
1710 aException = ::cppu::getCaughtException();
1711 bSuccess = false;
1714 // log the failure, if any
1715 if ( !bSuccess )
1717 m_rLogger.logRecoverable( MigrationError(
1718 ERR_SCRIPT_TRANSLATION_FAILURE,
1719 _rScriptType,
1720 _inout_rScriptCode,
1721 aException
1722 ) );
1725 return bSuccess;
1728 //--------------------------------------------------------------------
1729 bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( ScriptEventDescriptor& _inout_rScriptEvent ) const
1731 if ( _inout_rScriptEvent.ScriptType.getLength() && _inout_rScriptEvent.ScriptCode.getLength() )
1732 return impl_adjustScriptLibrary_nothrow( _inout_rScriptEvent.ScriptType, _inout_rScriptEvent.ScriptCode );
1733 return false;
1736 //--------------------------------------------------------------------
1737 bool MigrationEngine_Impl::impl_adjustScriptLibrary_nothrow( Any& _inout_rScriptDescriptor ) const
1739 ::comphelper::NamedValueCollection aScriptDesc( _inout_rScriptDescriptor );
1741 ::rtl::OUString sScriptType;
1742 ::rtl::OUString sScript;
1745 OSL_VERIFY( aScriptDesc.get_ensureType( "EventType", sScriptType ) );
1746 OSL_VERIFY( aScriptDesc.get_ensureType( "Script", sScript ) );
1748 catch( const Exception& )
1750 m_rLogger.logRecoverable( MigrationError(
1751 ERR_INVALID_SCRIPT_DESCRIPTOR_FORMAT,
1752 ::cppu::getCaughtException()
1753 ) );
1756 if ( sScriptType.getLength() && sScript.getLength() )
1757 if ( !impl_adjustScriptLibrary_nothrow( sScriptType, sScript ) )
1758 return false;
1760 aScriptDesc.put( "Script", sScript );
1761 _inout_rScriptDescriptor <<= aScriptDesc.getPropertyValues();
1762 return true;
1765 //--------------------------------------------------------------------
1766 bool MigrationEngine_Impl::impl_adjustDocumentEvents_nothrow( const SubDocument& _rDocument ) const
1770 Reference< XEventsSupplier > xSuppEvents( _rDocument.xDocument, UNO_QUERY );
1771 if ( !xSuppEvents.is() )
1772 // this is allowed. E.g. new-style reports currently do not support this
1773 return true;
1775 Reference< XNameReplace > xEvents( xSuppEvents->getEvents(), UNO_SET_THROW );
1776 Sequence< ::rtl::OUString > aEventNames = xEvents->getElementNames();
1778 Any aEvent;
1779 for ( const ::rtl::OUString* eventName = aEventNames.getConstArray();
1780 eventName != aEventNames.getConstArray() + aEventNames.getLength();
1781 ++eventName
1784 aEvent = xEvents->getByName( *eventName );
1785 if ( !aEvent.hasValue() )
1786 continue;
1788 // translate
1789 if ( !impl_adjustScriptLibrary_nothrow( aEvent ) )
1790 continue;
1792 // put back
1793 xEvents->replaceByName( *eventName, aEvent );
1796 catch( const Exception& )
1798 m_rLogger.logRecoverable( MigrationError(
1799 ERR_ADJUSTING_DOCUMENT_EVENTS_FAILED,
1800 lcl_getSubDocumentDescription( _rDocument ),
1801 ::cppu::getCaughtException()
1802 ) );
1803 return false;
1805 return true;
1808 //--------------------------------------------------------------------
1809 void MigrationEngine_Impl::impl_adjustDialogElementEvents_throw( const Reference< XInterface >& _rxElement ) const
1811 Reference< XScriptEventsSupplier > xEventsSupplier( _rxElement, UNO_QUERY_THROW );
1812 Reference< XNameReplace > xEvents( xEventsSupplier->getEvents(), UNO_QUERY_THROW );
1813 Sequence< ::rtl::OUString > aEventNames( xEvents->getElementNames() );
1815 const ::rtl::OUString* eventName = aEventNames.getArray();
1816 const ::rtl::OUString* eventNamesEnd = eventName + aEventNames.getLength();
1818 ScriptEventDescriptor aScriptEvent;
1819 for ( ; eventName != eventNamesEnd; ++eventName )
1821 OSL_VERIFY( xEvents->getByName( *eventName ) >>= aScriptEvent );
1823 if ( !impl_adjustScriptLibrary_nothrow( aScriptEvent ) )
1824 continue;
1826 xEvents->replaceByName( *eventName, makeAny( aScriptEvent ) );
1830 //--------------------------------------------------------------------
1831 bool MigrationEngine_Impl::impl_adjustDialogEvents_nothrow( Any& _inout_rDialogLibraryElement,
1832 const ::rtl::OUString& _rDocName, const ::rtl::OUString& _rDialogLibName, const ::rtl::OUString& _rDialogName ) const
1836 // load a dialog model from the stream describing it
1837 Reference< XInputStreamProvider > xISP( _inout_rDialogLibraryElement, UNO_QUERY_THROW );
1838 Reference< XInputStream > xInput( xISP->createInputStream(), UNO_QUERY_THROW );
1840 Reference< XNameContainer > xDialogModel( m_aContext.createComponent( "com.sun.star.awt.UnoControlDialogModel" ), UNO_QUERY_THROW );
1841 ::xmlscript::importDialogModel( xInput, xDialogModel, m_aContext.getUNOContext(), m_xDocumentModel );
1843 // adjust the events of the dialog
1844 impl_adjustDialogElementEvents_throw( xDialogModel );
1846 // adjust the events of the controls
1847 Sequence< ::rtl::OUString > aControlNames( xDialogModel->getElementNames() );
1848 const ::rtl::OUString* controlName = aControlNames.getConstArray();
1849 const ::rtl::OUString* controlNamesEnd = controlName + aControlNames.getLength();
1850 for ( ; controlName != controlNamesEnd; ++controlName )
1852 impl_adjustDialogElementEvents_throw( Reference< XInterface >( xDialogModel->getByName( *controlName ), UNO_QUERY ) );
1855 // export dialog model
1856 xISP = ::xmlscript::exportDialogModel( xDialogModel, m_aContext.getUNOContext(), m_xDocumentModel );
1857 _inout_rDialogLibraryElement <<= xISP;
1859 catch( const Exception& )
1861 m_rLogger.logRecoverable( MigrationError(
1862 ERR_ADJUSTING_DIALOG_EVENTS_FAILED,
1863 _rDocName,
1864 _rDialogLibName,
1865 _rDialogName,
1866 ::cppu::getCaughtException()
1867 ) );
1868 return false;
1870 return true;
1873 //--------------------------------------------------------------------
1874 void MigrationEngine_Impl::impl_adjustFormComponentEvents_throw( const Reference< XIndexAccess >& _rxComponentContainer ) const
1876 FormComponentIterator aCompIter( _rxComponentContainer );
1877 while ( aCompIter.hasMore() )
1879 // 1. adjust the component's scripts of the current component
1880 FormComponentScripts aComponent( aCompIter.next() );
1881 Sequence< ScriptEventDescriptor > aEvents( aComponent.getEvents() );
1883 bool bChangedComponentEvents = false;
1884 for ( ScriptEventDescriptor* scriptEvent = aEvents.getArray();
1885 scriptEvent != aEvents.getArray() + aEvents.getLength();
1886 ++scriptEvent
1889 if ( !impl_adjustScriptLibrary_nothrow( *scriptEvent ) )
1890 continue;
1892 bChangedComponentEvents = true;
1895 if ( bChangedComponentEvents )
1896 aComponent.setEvents( aEvents );
1898 // 2. step down if the component is a container itself
1899 Reference< XIndexAccess > xContainer( aComponent.getComponent(), UNO_QUERY );
1900 if ( xContainer.is() )
1901 impl_adjustFormComponentEvents_throw( xContainer );
1905 //--------------------------------------------------------------------
1906 bool MigrationEngine_Impl::impl_adjustFormComponentEvents_nothrow( const SubDocument& _rDocument ) const
1910 DrawPageIterator aPageIter( _rDocument.xDocument );
1911 while ( aPageIter.hasMore() )
1913 Reference< XFormsSupplier > xSuppForms( aPageIter.next(), UNO_QUERY_THROW );
1914 Reference< XIndexAccess > xForms( xSuppForms->getForms(), UNO_QUERY_THROW );
1915 impl_adjustFormComponentEvents_throw( xForms );
1918 catch( const Exception& )
1920 m_rLogger.logRecoverable( MigrationError(
1921 ERR_ADJUSTING_FORMCOMP_EVENTS_FAILED,
1922 lcl_getSubDocumentDescription( _rDocument ),
1923 ::cppu::getCaughtException()
1924 ) );
1925 return false;
1927 return true;
1930 //--------------------------------------------------------------------
1931 bool MigrationEngine_Impl::impl_unprotectPasswordLibrary_throw( const Reference< XLibraryContainerPassword >& _rxPasswordManager,
1932 const ScriptType _eScriptType, const ::rtl::OUString& _rLibraryName ) const
1934 // a human-readable description of the affected library
1935 ::rtl::OUString sLibraryDescription( String(
1936 MacroMigrationResId( STR_LIBRARY_TYPE_AND_NAME ) ) );
1937 ::comphelper::string::searchAndReplaceAsciiI( sLibraryDescription, "$type$",
1938 getScriptTypeDisplayName( _eScriptType ) );
1939 ::comphelper::string::searchAndReplaceAsciiI( sLibraryDescription, "$library$",
1940 _rLibraryName );
1942 InteractionHandler aHandler( m_aContext, m_xDocumentModel );
1943 ::rtl::OUString sPassword;
1944 while ( true )
1946 if ( !aHandler.requestDocumentPassword( sLibraryDescription, sPassword ) )
1947 // aborted by the user
1948 return false;
1950 bool bSuccessVerification = _rxPasswordManager->verifyLibraryPassword( _rLibraryName, sPassword );
1951 if ( bSuccessVerification )
1952 return true;
1957 //====================================================================
1958 //= MigrationEngine
1959 //====================================================================
1960 //--------------------------------------------------------------------
1961 MigrationEngine::MigrationEngine( const ::comphelper::ComponentContext& _rContext,
1962 const Reference< XOfficeDatabaseDocument >& _rxDocument, IMigrationProgress& _rProgress,
1963 MigrationLog& _rLogger )
1964 :m_pImpl( new MigrationEngine_Impl( _rContext, _rxDocument, _rProgress, _rLogger ) )
1968 //--------------------------------------------------------------------
1969 MigrationEngine::~MigrationEngine()
1973 //--------------------------------------------------------------------
1974 sal_Int32 MigrationEngine::getFormCount() const
1976 return m_pImpl->getFormCount();
1979 //--------------------------------------------------------------------
1980 sal_Int32 MigrationEngine::getReportCount() const
1982 return m_pImpl->getReportCount();
1985 //--------------------------------------------------------------------
1986 bool MigrationEngine::migrateAll()
1988 return m_pImpl->migrateAll();
1991 //........................................................................
1992 } // namespace dbmm
1993 //........................................................................