diff options
author | Rüdiger Timm <rt@openoffice.org> | 2008-12-09 07:25:38 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2008-12-09 07:25:38 +0000 |
commit | 568af9ac86c8eee3531ff9cb718aeba240f274be (patch) | |
tree | 710059fbd5080acac11680bc02bf27761346e17b /dbaccess/source/ext/macromigration/migrationengine.cxx | |
parent | b4e6996966166bf80447fc9eda619b283e8c86ef (diff) |
CWS-TOOLING: integrate CWS dba31d
2008-12-08 16:22:07 +0100 rt r265005 : Remove DOS lineends
2008-12-05 13:56:24 +0100 fs r264906 : #i10000# removed unreachable statement
2008-11-20 11:41:26 +0100 fs r264037 : merged in the fix for #i95865# (it was wrongly committed to CWS dba32a, should have been here)
2008-11-20 11:34:24 +0100 fs r264036 : line ends
2008-11-14 08:44:50 +0100 lla r263665 : #i10000# comparsion between int and uint fixed
2008-11-13 13:31:12 +0100 lla r263641 : #i10000# build problem fixed
2008-11-13 11:20:01 +0100 lla r263625 : #i96130# hard code name of extension
2008-11-12 11:13:41 +0100 fs r263582 : #i96096# when opening a SRB-report fails due to the missing SRB extension, log this as warning only, and proceed with the migration
2008-11-12 11:11:35 +0100 fs r263581 : #i96096# ContentType handling. Now all contents deliver proper results in XContent::getContentType
2008-11-12 11:10:11 +0100 fs r263580 : #i96096# new ctors taking UNO_QUERY_THROW
2008-11-11 10:10:13 +0100 lla r263546 : CWS-TOOLING: rebase CWS dba31d to trunk@263288 (milestone: DEV300:m35)
2008-11-06 15:55:39 +0100 oj r263393 : #i93452# get field from model fallbackis the name
2008-11-06 15:31:47 +0100 oj r263392 : #i93465# remeber location of floating windows
2008-11-06 13:36:24 +0100 oj r263381 : #i93450# check typemap for null
2008-11-06 13:28:49 +0100 oj r263379 : #i93020# empty column list boxes when new relation should be created
2008-11-06 12:33:53 +0100 oj r263377 : #i93012# set border to default : flat
2008-11-06 12:26:54 +0100 oj r263375 : #i74927# do some less calls for odbc
2008-11-06 09:34:01 +0100 oj r263362 : #i93383# grabFocus in suspend to get allmodified cells
2008-11-03 21:01:39 +0100 oj r263308 : #i86739# check if slash can be valid for tables
2008-11-03 14:40:21 +0100 oj r263287 : #i86739# check if slash can be valid for tables
2008-11-03 14:32:17 +0100 oj r263286 : #i95227# column width
2008-11-03 14:27:26 +0100 oj r263285 : link fwe
2008-11-03 14:24:54 +0100 oj r263284 : #i95235# changed to hold no ref only weak
2008-10-31 11:21:48 +0100 oj r262859 : #i93459# set images add menu entry
2008-10-31 09:06:37 +0100 oj r262851 : #i88629# correct fileopen filter for database odb files
2008-10-30 15:01:04 +0100 oj r262828 : #i95229# set filter at the composer
2008-10-29 15:57:41 +0100 oj r262817 : #i95235# changed to hold no ref only weak
2008-10-29 15:57:19 +0100 oj r262816 : #i95235# changed to hold no ref only weak
2008-10-29 15:57:03 +0100 oj r262815 : #i95235# changed to hold no ref only weak
2008-10-29 15:56:15 +0100 oj r262814 : #i95235# filtermanger changed to hold no ref only weak
2008-10-29 10:32:39 +0100 oj r262773 : #i93474# use correct table name
2008-10-28 13:49:33 +0100 lla r262744 : #i95524# make an Invalidate and refresh on Tables
2008-10-28 10:45:02 +0100 fs r262707 : line ends
2008-10-28 10:34:42 +0100 fs r262706 : #i95522# don't expect the component to live in a TopWindow
2008-10-28 08:30:40 +0100 lla r262696 : #i93176# set preview mode on view
2008-10-28 07:56:57 +0100 oj r262694 : merge cvs svn
2008-10-27 14:13:51 +0100 oj r262673 : #i94129# use dummy data
2008-10-27 12:38:45 +0100 fs r262669 : #i94125# rework ScrollColumns
2008-10-23 15:53:57 +0200 oj r262624 : #i94568# do not load the embeddedobj just copy the storage
2008-10-23 14:39:14 +0200 oj r262622 : #i94129# handle chart correctly
2008-10-22 10:51:19 +0200 lla r262582 : #i94115# problem with left walk chart shape fixed
2008-10-22 07:47:48 +0200 oj r262576 : #i94455# rename now do not use remove insert
2008-10-22 07:47:27 +0200 oj r262575 : #i94455# rename now do not use remove insert
2008-10-21 12:46:26 +0200 lla r262567 : #i93845# extra check if default schema doesn't exists, fix assertion
Diffstat (limited to 'dbaccess/source/ext/macromigration/migrationengine.cxx')
-rw-r--r-- | dbaccess/source/ext/macromigration/migrationengine.cxx | 178 |
1 files changed, 132 insertions, 46 deletions
diff --git a/dbaccess/source/ext/macromigration/migrationengine.cxx b/dbaccess/source/ext/macromigration/migrationengine.cxx index 824e236ef9eb..9c1447bb84da 100644 --- a/dbaccess/source/ext/macromigration/migrationengine.cxx +++ b/dbaccess/source/ext/macromigration/migrationengine.cxx @@ -49,6 +49,7 @@ #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/ucb/XContent.hpp> #include <com/sun/star/embed/XComponentSupplier.hpp> #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/document/XStorageBasedDocument.hpp> @@ -66,11 +67,13 @@ #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/script/XEventAttacherManager.hpp> #include <com/sun/star/script/XLibraryContainerPassword.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> /** === end UNO includes === **/ #include <comphelper/documentinfo.hxx> #include <comphelper/interaction.hxx> #include <comphelper/namedvaluecollection.hxx> +#include <comphelper/storagehelper.hxx> #include <comphelper/string.hxx> #include <comphelper/types.hxx> #include <cppuhelper/exc_hlp.hxx> @@ -111,6 +114,7 @@ namespace dbmm using ::com::sun::star::frame::XModel; using ::com::sun::star::frame::XComponentLoader; using ::com::sun::star::ucb::XCommandProcessor; + using ::com::sun::star::ucb::XContent; using ::com::sun::star::ucb::Command; using ::com::sun::star::embed::XComponentSupplier; using ::com::sun::star::task::XStatusIndicator; @@ -138,6 +142,7 @@ namespace dbmm using ::com::sun::star::script::XEventAttacherManager; using ::com::sun::star::script::ScriptEventDescriptor; using ::com::sun::star::script::XLibraryContainerPassword; + using ::com::sun::star::io::WrongFormatException; /** === end UNO using === **/ namespace ElementModes = ::com::sun::star::embed::ElementModes; @@ -158,12 +163,15 @@ namespace dbmm Reference< XModel > xDocument; // valid only temporarily ::rtl::OUString sHierarchicalName; SubDocumentType eType; + size_t nNumber; - SubDocument( const Reference< XCommandProcessor >& _rxCommandProcessor, const ::rtl::OUString& _rName, const SubDocumentType _eType ) + SubDocument( const Reference< XCommandProcessor >& _rxCommandProcessor, const ::rtl::OUString& _rName, + const SubDocumentType _eType, const size_t _nNumber ) :xCommandProcessor( _rxCommandProcessor ) ,xDocument() ,sHierarchicalName( _rName ) ,eType( _eType ) + ,nNumber( _nNumber ) { } }; @@ -265,7 +273,31 @@ namespace dbmm } //---------------------------------------------------------------- - static bool lcl_loadSubDocument_nothrow( SubDocument& _rDocument, + ::rtl::OUString lcl_getMimeType_nothrow( const Reference< XCommandProcessor >& _rxContent ) + { + ::rtl::OUString sMimeType; + try + { + Reference< XContent > xContent( _rxContent, UNO_QUERY_THROW ); + sMimeType = xContent->getContentType(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return sMimeType; + } + + //---------------------------------------------------------------- + enum OpenDocResult + { + eOpenedDoc, + eIgnoreDoc, + eFailure + }; + + //---------------------------------------------------------------- + static OpenDocResult lcl_loadSubDocument_nothrow( SubDocument& _rDocument, const Reference< XStatusIndicator >& _rxProgress, MigrationLog& _rLogger ) { OSL_PRECOND( !_rDocument.xDocument.is(), "lcl_loadSubDocument_nothrow: already loaded!" ); @@ -292,13 +324,31 @@ namespace dbmm } catch( const Exception& ) { - _rLogger.logFailure( MigrationError( - ERR_OPENING_SUB_DOCUMENT_FAILED, - lcl_getSubDocumentDescription( _rDocument ), - ::cppu::getCaughtException() - ) ); + Any aError( ::cppu::getCaughtException() ); + + bool bCausedByNewStyleReport = + ( _rDocument.eType == eReport ) + && ( aError.isExtractableTo( ::cppu::UnoType< WrongFormatException >::get() ) ) + && ( lcl_getMimeType_nothrow( _rDocument.xCommandProcessor ).equalsAscii( "application/vnd.sun.xml.report" ) ); + + if ( bCausedByNewStyleReport ) + { + _rLogger.logRecoverable( MigrationError( + ERR_NEW_STYLE_REPORT, + lcl_getSubDocumentDescription( _rDocument ) + ) ); + return eIgnoreDoc; + } + else + { + _rLogger.logFailure( MigrationError( + ERR_OPENING_SUB_DOCUMENT_FAILED, + lcl_getSubDocumentDescription( _rDocument ), + aError + ) ); + } } - return _rDocument.xDocument.is(); + return _rDocument.xDocument.is() ? eOpenedDoc : eFailure; } //---------------------------------------------------------------- @@ -822,8 +872,8 @@ namespace dbmm ); ~MigrationEngine_Impl(); - inline sal_Int32 getFormCount() const { return m_nFormCount; } - inline sal_Int32 getReportCount()const { return m_nReportCount; } + inline size_t getFormCount() const { return m_nFormCount; } + inline size_t getReportCount()const { return m_nReportCount; } bool migrateAll(); private: @@ -995,12 +1045,10 @@ namespace dbmm //-------------------------------------------------------------------- namespace { - size_t lcl_collectHierarchicalElementNames_throw( + void lcl_collectHierarchicalElementNames_throw( const Reference< XNameAccess >& _rxContainer, const ::rtl::OUString& _rContainerLoc, - SubDocuments& _out_rDocs, const SubDocumentType _eType ) + SubDocuments& _out_rDocs, const SubDocumentType _eType, size_t& _io_counter ) { - size_t nAddedElements = 0; - const ::rtl::OUString sHierarhicalBase( _rContainerLoc.getLength() ? ::rtl::OUStringBuffer( _rContainerLoc ).appendAscii( "/" ).makeStringAndClear() : ::rtl::OUString() ); @@ -1017,7 +1065,7 @@ namespace dbmm Reference< XNameAccess > xSubContainer( aElement, UNO_QUERY ); if ( xSubContainer.is() ) { - nAddedElements += lcl_collectHierarchicalElementNames_throw( xSubContainer, sElementName, _out_rDocs, _eType ); + lcl_collectHierarchicalElementNames_throw( xSubContainer, sElementName, _out_rDocs, _eType, _io_counter ); } else { @@ -1025,12 +1073,10 @@ namespace dbmm 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; + _out_rDocs.push_back( SubDocument( xCommandProcessor, sElementName, _eType, ++_io_counter ) ); } } } - return nAddedElements; } } @@ -1044,10 +1090,12 @@ namespace dbmm try { Reference< XNameAccess > xDocContainer( m_xDocument->getFormDocuments(), UNO_SET_THROW ); - m_nFormCount = lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eForm ); + m_nFormCount = 0; + lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eForm, m_nFormCount ); xDocContainer.set( m_xDocument->getReportDocuments(), UNO_SET_THROW ); - m_nReportCount = lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eReport ); + m_nReportCount = 0; + lcl_collectHierarchicalElementNames_throw( xDocContainer, ::rtl::OUString(), m_aSubDocs, eReport, m_nReportCount ); } catch( const Exception& ) { @@ -1075,13 +1123,14 @@ namespace dbmm // load the document ::rtl::Reference< ProgressCapture > pStatusIndicator( new ProgressCapture( sObjectName, m_rProgress ) ); SubDocument aSubDocument( _rDocument ); - if ( !lcl_loadSubDocument_nothrow( aSubDocument, pStatusIndicator.get(), m_rLogger ) ) + OpenDocResult eResult = lcl_loadSubDocument_nothrow( aSubDocument, pStatusIndicator.get(), m_rLogger ); + if ( eResult != eOpenedDoc ) { pStatusIndicator->dispose(); m_rProgress.endObject(); m_rLogger.finishedDocument( m_nCurrentDocumentID ); m_nCurrentDocumentID = -1; - return false; + return ( eResult == eIgnoreDoc ); } // ----------------- @@ -1145,32 +1194,69 @@ namespace dbmm namespace { static ::rtl::OUString lcl_createTargetLibName( const SubDocument& _rDocument, - const ::rtl::OUString& _rSourceLibName, const Reference< XNameAccess >& _rxTargetStorage ) + const ::rtl::OUString& _rSourceLibName, const Reference< XNameAccess >& _rxTargetContainer ) { - // a prefix denoting the type + // The new library name is composed from the prefix, the base name, and the old library name. const ::rtl::OUString sPrefix( ::rtl::OUString::createFromAscii( _rDocument.eType == eForm ? "Form_" : "Report_" ) ); - ::rtl::OUStringBuffer aBuffer; - aBuffer.append( sPrefix ); - - // first try with the base name of the sub document - aBuffer.append( _rDocument.sHierarchicalName.copy( + ::rtl::OUString sBaseName( _rDocument.sHierarchicalName.copy( _rDocument.sHierarchicalName.lastIndexOf( '/' ) + 1 ) ); - aBuffer.appendAscii( "_" ); - aBuffer.append( _rSourceLibName ); - ::rtl::OUString sTargetName( aBuffer.makeStringAndClear() ); - if ( !_rxTargetStorage->hasByName( sTargetName ) ) - return sTargetName; - - // if this name is already used (which is valid, since documents with the same base - // name can exist in different logical folders), then use the complete name - aBuffer.append( sPrefix ); - aBuffer.append( ::comphelper::string::searchAndReplaceAllAsciiWithAscii( - _rDocument.sHierarchicalName, "/", "_" ) ); - aBuffer.appendAscii( "_" ); - aBuffer.append( _rSourceLibName ); - return aBuffer.makeStringAndClear(); + // Normalize this name. In our current storage implementation (and script containers in a document + // are finally mapped to sub storages of the document storage), not all characters are allowed. + // The bug requesting to change this is #i95409#. + // Unfortunately, the storage implementation does not complain if you use invalid characters/names, but instead + // it silently accepts them, and produces garbage in the file (#i95408). + // So, until especially the former is fixed, we need to strip the name from all invalid characters. + // #i95865# / 2008-11-06 / frank.schoenheit@sun.com + + // The general idea is to replace invalid characters with '_'. However, since "valid" essentially means + // ASCII only, this implies that for a lot of languages, we would simply replace everything with '_', + // which of course is not desired. + // So, we use a heuristics: If the name contains at most 3 invalid characters, and as many valid as invalid + // characters, then we use the replacement. Otherwise, we just use a unambiguous number for the sub document. + sal_Int32 nValid=0, nInvalid=0; + const sal_Unicode* pBaseName = sBaseName.getStr(); + const sal_Int32 nBaseNameLen = sBaseName.getLength(); + for ( sal_Int32 i=0; i<nBaseNameLen; ++i ) + { + if ( ::comphelper::IsValidZipEntryFileName( pBaseName + i, 1, sal_False ) ) + ++nValid; + else + ++nInvalid; + } + if ( ( nInvalid <= 3 ) && ( nInvalid * 2 <= nValid ) ) + { // not "too many" invalid => replace them + ::rtl::OUStringBuffer aReplacement; + aReplacement.ensureCapacity( nBaseNameLen ); + aReplacement.append( sBaseName ); + const sal_Unicode* pReplacement = aReplacement.getStr(); + for ( sal_Int32 i=0; i<nBaseNameLen; ++i ) + { + if ( !::comphelper::IsValidZipEntryFileName( pReplacement + i, 1, sal_False ) ) + aReplacement.setCharAt( i, '_' ); + } + sBaseName = aReplacement.makeStringAndClear(); + + ::rtl::OUStringBuffer aNewLibNameAttempt; + aNewLibNameAttempt.append( sPrefix ); + aNewLibNameAttempt.append( sBaseName ); + aNewLibNameAttempt.appendAscii( "_" ); + aNewLibNameAttempt.append( _rSourceLibName ); + ::rtl::OUString sTargetName( aNewLibNameAttempt.makeStringAndClear() ); + if ( !_rxTargetContainer->hasByName( sTargetName ) ) + return sTargetName; + } + // "too many" invalid characters, or the name composed with the base name was already used. + // (The latter is valid, since there can be multiple sub documents with the same base name, + // in different levels in the hierarchy.) + // In this case, just use the umambiguous sub document number. + ::rtl::OUStringBuffer aNewLibName; + aNewLibName.append( sPrefix ); + aNewLibName.append( ::rtl::OUString::valueOf( sal_Int64( _rDocument.nNumber ) ) ); + aNewLibName.appendAscii( "_" ); + aNewLibName.append( _rSourceLibName ); + return aNewLibName.makeStringAndClear(); } } @@ -1314,8 +1400,8 @@ namespace dbmm { m_rLogger.logFailure( MigrationError( ERR_COMMITTING_SCRIPT_STORAGES_FAILED, - lcl_getSubDocumentDescription( _rDocument ), - getScriptTypeDisplayName( _eScriptType ) + getScriptTypeDisplayName( _eScriptType ), + lcl_getSubDocumentDescription( _rDocument ) ) ); return false; } @@ -1340,8 +1426,8 @@ namespace dbmm { m_rLogger.logFailure( MigrationError( ERR_GENERAL_SCRIPT_MIGRATION_FAILURE, - lcl_getSubDocumentDescription( _rDocument ), getScriptTypeDisplayName( _eScriptType ), + lcl_getSubDocumentDescription( _rDocument ), aException ) ); } |