1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dbaccess.hxx" 30 31 #include "dbmm_module.hxx" 32 #include "dbmm_global.hrc" 33 #include "migrationerror.hxx" 34 #include "migrationlog.hxx" 35 36 /** === begin UNO includes === **/ 37 /** === end UNO includes === **/ 38 39 #include <comphelper/anytostring.hxx> 40 #include <comphelper/string.hxx> 41 #include <tools/string.hxx> 42 #include <rtl/ustrbuf.hxx> 43 44 #include <vector> 45 #include <map> 46 #include <list> 47 48 //........................................................................ 49 namespace dbmm 50 { 51 //........................................................................ 52 53 /** === begin UNO using === **/ 54 /** === end UNO using === **/ 55 56 //==================================================================== 57 //= LibraryEntry 58 //==================================================================== 59 struct LibraryEntry 60 { 61 ScriptType eType; 62 ::rtl::OUString sOldName; 63 ::rtl::OUString sNewName; 64 65 LibraryEntry() 66 :eType( eBasic ) 67 ,sOldName() 68 ,sNewName() 69 { 70 } 71 72 LibraryEntry( const ScriptType& _eType, const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName ) 73 :eType( _eType ) 74 ,sOldName( _rOldName ) 75 ,sNewName( _rNewName ) 76 { 77 } 78 }; 79 80 //==================================================================== 81 //= DocumentEntry 82 //==================================================================== 83 struct DocumentEntry 84 { 85 SubDocumentType eType; 86 ::rtl::OUString sName; 87 ::std::vector< LibraryEntry > aMovedLibraries; 88 89 DocumentEntry() 90 :eType( eForm ) 91 ,sName() 92 ,aMovedLibraries() 93 { 94 } 95 96 DocumentEntry( const SubDocumentType _eType, const ::rtl::OUString& _rName ) 97 :eType( _eType ) 98 ,sName( _rName ) 99 { 100 } 101 }; 102 103 //==================================================================== 104 //= DocumentLogs 105 //==================================================================== 106 typedef ::std::map< DocumentID, DocumentEntry > DocumentLogs; 107 108 //==================================================================== 109 //= ErrorLog 110 //==================================================================== 111 typedef ::std::list< MigrationError > ErrorLog; 112 113 //==================================================================== 114 //= MigrationLog_Data 115 //==================================================================== 116 struct MigrationLog_Data 117 { 118 ::rtl::OUString sBackupLocation; 119 DocumentLogs aDocumentLogs; 120 ErrorLog aFailures; 121 ErrorLog aWarnings; 122 }; 123 124 //==================================================================== 125 //= MigrationLog 126 //==================================================================== 127 //-------------------------------------------------------------------- 128 MigrationLog::MigrationLog() 129 :m_pData( new MigrationLog_Data ) 130 { 131 } 132 133 //-------------------------------------------------------------------- 134 MigrationLog::~MigrationLog() 135 { 136 } 137 138 //-------------------------------------------------------------------- 139 void MigrationLog::logFailure( const MigrationError& _rError ) 140 { 141 m_pData->aFailures.push_back( _rError ); 142 } 143 144 //-------------------------------------------------------------------- 145 void MigrationLog::logRecoverable( const MigrationError& _rError ) 146 { 147 m_pData->aWarnings.push_back( _rError ); 148 } 149 150 //-------------------------------------------------------------------- 151 bool MigrationLog::hadFailure() const 152 { 153 return !m_pData->aFailures.empty(); 154 } 155 156 //-------------------------------------------------------------------- 157 void MigrationLog::backedUpDocument( const ::rtl::OUString& _rNewDocumentLocation ) 158 { 159 m_pData->sBackupLocation = _rNewDocumentLocation; 160 } 161 162 //-------------------------------------------------------------------- 163 DocumentID MigrationLog::startedDocument( const SubDocumentType _eType, const ::rtl::OUString& _rName ) 164 { 165 #if OSL_DEBUG_LEVEL > 0 166 bool bAlreadyKnown = false; 167 for ( DocumentLogs::const_iterator doc = m_pData->aDocumentLogs.begin(); 168 doc != m_pData->aDocumentLogs.end() && !bAlreadyKnown; 169 ++doc 170 ) 171 { 172 bAlreadyKnown = ( doc->second.eType == _eType ) && ( doc->second.sName == _rName ); 173 } 174 OSL_ENSURE( !bAlreadyKnown, "MigrationLog::startedDocument: document is already known!" ); 175 #endif 176 177 DocumentID nID = (DocumentID)( m_pData->aDocumentLogs.size() + 1 ); 178 while ( m_pData->aDocumentLogs.find( nID ) != m_pData->aDocumentLogs.end() ) 179 ++nID; 180 181 m_pData->aDocumentLogs[ nID ] = DocumentEntry( _eType, _rName ); 182 183 return nID; 184 } 185 186 //-------------------------------------------------------------------- 187 void MigrationLog::movedLibrary( const DocumentID _nDocID, const ScriptType _eScriptType, 188 const ::rtl::OUString& _rOriginalLibName, const ::rtl::OUString& _rNewLibName ) 189 { 190 OSL_ENSURE( m_pData->aDocumentLogs.find( _nDocID ) != m_pData->aDocumentLogs.end(), 191 "MigrationLog::movedLibrary: document is not known!" ); 192 193 DocumentEntry& rDocEntry = m_pData->aDocumentLogs[ _nDocID ]; 194 rDocEntry.aMovedLibraries.push_back( LibraryEntry( _eScriptType, _rOriginalLibName, _rNewLibName ) ); 195 } 196 197 //-------------------------------------------------------------------- 198 void MigrationLog::finishedDocument( const DocumentID _nDocID ) 199 { 200 OSL_ENSURE( m_pData->aDocumentLogs.find( _nDocID ) != m_pData->aDocumentLogs.end(), 201 "MigrationLog::finishedDocument: document is not known!" ); 202 203 DocumentEntry& rDocEntry = m_pData->aDocumentLogs[ _nDocID ]; 204 (void)rDocEntry; 205 // nothing to do here 206 } 207 208 //-------------------------------------------------------------------- 209 const ::rtl::OUString& MigrationLog::getNewLibraryName( DocumentID _nDocID, ScriptType _eScriptType, 210 const ::rtl::OUString& _rOriginalLibName ) const 211 { 212 static ::rtl::OUString s_sEmptyString; 213 214 DocumentLogs::const_iterator docPos = m_pData->aDocumentLogs.find( _nDocID ); 215 if ( docPos == m_pData->aDocumentLogs.end() ) 216 { 217 OSL_ENSURE( false, "MigrationLog::getNewLibraryName: document is not known!" ); 218 return s_sEmptyString; 219 } 220 221 const DocumentEntry& rDocEntry( docPos->second ); 222 for ( ::std::vector< LibraryEntry >::const_iterator lib = rDocEntry.aMovedLibraries.begin(); 223 lib != rDocEntry.aMovedLibraries.end(); 224 ++lib 225 ) 226 { 227 if ( ( _eScriptType == lib->eType ) 228 && ( _rOriginalLibName == lib->sOldName ) 229 ) 230 return lib->sNewName; 231 } 232 233 OSL_ENSURE( false, "MigrationLog::getNewLibraryName: doc is known, but library isn't!" ); 234 return s_sEmptyString; 235 } 236 237 //-------------------------------------------------------------------- 238 namespace 239 { 240 //---------------------------------------------------------------- 241 static void lcl_appendErrorDescription( ::rtl::OUStringBuffer& _inout_rBuffer, const MigrationError& _rError ) 242 { 243 const sal_Char* pAsciiErrorDescription( NULL ); 244 ::std::vector< const sal_Char* > aAsciiParameterNames; 245 switch ( _rError.eType ) 246 { 247 case ERR_OPENING_SUB_DOCUMENT_FAILED: 248 pAsciiErrorDescription = "opening '#doc#' failed"; 249 aAsciiParameterNames.push_back( "#doc#" ); 250 break; 251 252 case ERR_CLOSING_SUB_DOCUMENT_FAILED: 253 pAsciiErrorDescription = "closing '#doc#' failed"; 254 aAsciiParameterNames.push_back( "#doc#" ); 255 break; 256 257 case ERR_STORAGE_COMMIT_FAILED: 258 pAsciiErrorDescription = "committing the changes for document '#doc#' failed"; 259 aAsciiParameterNames.push_back( "#doc#" ); 260 break; 261 262 case ERR_STORING_DATABASEDOC_FAILED: 263 pAsciiErrorDescription = "storing the database document failed"; 264 break; 265 266 case ERR_COLLECTING_DOCUMENTS_FAILED: 267 pAsciiErrorDescription = "collecting the forms/reports of the database document failed"; 268 break; 269 270 case ERR_UNEXPECTED_LIBSTORAGE_ELEMENT: 271 pAsciiErrorDescription = "unexpected #lib# storage element in document '#doc#', named '#element#'"; 272 aAsciiParameterNames.push_back( "#doc#" ); 273 aAsciiParameterNames.push_back( "#libstore#" ); 274 aAsciiParameterNames.push_back( "#element#" ); 275 break; 276 277 case ERR_CREATING_DBDOC_SCRIPT_STORAGE_FAILED: 278 pAsciiErrorDescription = "creating the database document's storage for #scripttype# scripts failed"; 279 aAsciiParameterNames.push_back( "#scripttype#" ); 280 break; 281 282 case ERR_COMMITTING_SCRIPT_STORAGES_FAILED: 283 pAsciiErrorDescription = "saving the #scripttype# scripts for document '#doc#' failed"; 284 aAsciiParameterNames.push_back( "#scripttype#" ); 285 aAsciiParameterNames.push_back( "#doc#" ); 286 break; 287 288 case ERR_GENERAL_SCRIPT_MIGRATION_FAILURE: 289 pAsciiErrorDescription = "general error while migrating #scripttype# scripts of document '#doc#'"; 290 aAsciiParameterNames.push_back( "#scripttype#" ); 291 aAsciiParameterNames.push_back( "#doc#" ); 292 break; 293 294 case ERR_GENERAL_MACRO_MIGRATION_FAILURE: 295 pAsciiErrorDescription = "general error during macro migration of document '#doc#'"; 296 aAsciiParameterNames.push_back( "#doc#" ); 297 break; 298 299 case ERR_UNKNOWN_SCRIPT_TYPE: 300 pAsciiErrorDescription = "unknown script type: #type#"; 301 aAsciiParameterNames.push_back( "#type#" ); 302 break; 303 304 case ERR_UNKNOWN_SCRIPT_LANGUAGE: 305 pAsciiErrorDescription = "unknown script language: #lang#"; 306 aAsciiParameterNames.push_back( "#lang#" ); 307 break; 308 309 case ERR_UNKNOWN_SCRIPT_NAME_FORMAT: 310 pAsciiErrorDescription = "unknown script name format: #script#"; 311 aAsciiParameterNames.push_back( "#script#" ); 312 break; 313 314 case ERR_SCRIPT_TRANSLATION_FAILURE: 315 pAsciiErrorDescription = "analyzing/translating the script URL failed; script type: #type#; script: #code#"; 316 aAsciiParameterNames.push_back( "#type#" ); 317 aAsciiParameterNames.push_back( "#code#" ); 318 break; 319 320 case ERR_INVALID_SCRIPT_DESCRIPTOR_FORMAT: 321 pAsciiErrorDescription = "invalid script descriptor format"; 322 break; 323 324 case ERR_ADJUSTING_DOCUMENT_EVENTS_FAILED: 325 pAsciiErrorDescription = "adjusting events for document '#doc#' failed"; 326 aAsciiParameterNames.push_back( "#doc#" ); 327 break; 328 329 case ERR_ADJUSTING_DIALOG_EVENTS_FAILED: 330 pAsciiErrorDescription = "adjusting events for dialog #lib#.#dlg# in document '#doc#' failed"; 331 aAsciiParameterNames.push_back( "#doc#" ); 332 aAsciiParameterNames.push_back( "#lib#" ); 333 aAsciiParameterNames.push_back( "#dlg#" ); 334 break; 335 336 case ERR_ADJUSTING_FORMCOMP_EVENTS_FAILED: 337 pAsciiErrorDescription = "adjusting form component events for '#doc#' failed"; 338 aAsciiParameterNames.push_back( "#doc#" ); 339 break; 340 341 case ERR_BIND_SCRIPT_STORAGE_FAILED: 342 pAsciiErrorDescription = "binding to the script storage failed for document '#doc#'"; 343 aAsciiParameterNames.push_back( "#doc#" ); 344 break; 345 346 case ERR_REMOVE_SCRIPTS_STORAGE_FAILED: 347 pAsciiErrorDescription = "removing a scripts storage failed for document '#doc#'"; 348 aAsciiParameterNames.push_back( "#doc#" ); 349 break; 350 351 case ERR_DOCUMENT_BACKUP_FAILED: 352 pAsciiErrorDescription = "backing up the document to #location# failed"; 353 aAsciiParameterNames.push_back( "#location#" ); 354 break; 355 356 case ERR_UNKNOWN_SCRIPT_FOLDER: 357 pAsciiErrorDescription = "unknown script folder '#name#' in document '#doc#'"; 358 aAsciiParameterNames.push_back( "#doc#" ); 359 aAsciiParameterNames.push_back( "#name#" ); 360 break; 361 362 case ERR_EXAMINING_SCRIPTS_FOLDER_FAILED: 363 pAsciiErrorDescription = "examining the 'Scripts' folder failed for document '#doc#'"; 364 aAsciiParameterNames.push_back( "#doc#" ); 365 break; 366 367 case ERR_PASSWORD_VERIFICATION_FAILED: 368 pAsciiErrorDescription = "password verification failed for document '#doc#', #libtype# library '#name#'"; 369 aAsciiParameterNames.push_back( "#doc#" ); 370 aAsciiParameterNames.push_back( "#libtype#" ); 371 aAsciiParameterNames.push_back( "#name#" ); 372 break; 373 374 case ERR_NEW_STYLE_REPORT: 375 pAsciiErrorDescription = "#doc# could not be processed, since you don't have the Oracle Report Builder (TM) extension installed."; 376 aAsciiParameterNames.push_back( "#doc#" ); 377 break; 378 379 // do *not* add a default case here: Without a default, some compilers will warn you when 380 // you miss a newly-introduced enum value here 381 } 382 OSL_ENSURE( pAsciiErrorDescription, "lcl_appendErrorDescription: no error message!" ); 383 if ( pAsciiErrorDescription ) 384 { 385 ::rtl::OUString sSubstituted( ::rtl::OUString::createFromAscii( pAsciiErrorDescription ) ); 386 OSL_ENSURE( aAsciiParameterNames.size() == _rError.aErrorDetails.size(), 387 "lcl_appendErrorDescription: unexpected number of error message parameters!" ); 388 389 for ( size_t i=0; i < ::std::min( aAsciiParameterNames.size(), _rError.aErrorDetails.size() ); ++i ) 390 { 391 ::comphelper::string::searchAndReplaceAsciiI( sSubstituted, aAsciiParameterNames[i], 392 _rError.aErrorDetails[i] ); 393 } 394 395 _inout_rBuffer.append( sSubstituted ); 396 } 397 } 398 399 //---------------------------------------------------------------- 400 void lcl_describeErrors( ::rtl::OUStringBuffer& _rBuffer, const ErrorLog& _rErrors, const sal_uInt16 _nHeadingResId ) 401 { 402 _rBuffer.appendAscii( "=== " ); 403 _rBuffer.append ( String( MacroMigrationResId( _nHeadingResId ) ) ); 404 _rBuffer.appendAscii( " ===\n" ); 405 406 String sException( MacroMigrationResId( STR_EXCEPTION ) ); 407 408 for ( ErrorLog::const_iterator error = _rErrors.begin(); 409 error != _rErrors.end(); 410 ++error 411 ) 412 { 413 _rBuffer.append( sal_Unicode( '-' ) ); 414 _rBuffer.append( sal_Unicode( ' ' ) ); 415 lcl_appendErrorDescription( _rBuffer, *error ); 416 _rBuffer.append( sal_Unicode( '\n' ) ); 417 418 if ( !error->aCaughtException.hasValue() ) 419 continue; 420 421 _rBuffer.append( sException ); 422 _rBuffer.append( ::comphelper::anyToString( error->aCaughtException ) ); 423 _rBuffer.append( sal_Unicode( '\n' ) ); 424 _rBuffer.append( sal_Unicode( '\n' ) ); 425 } 426 } 427 } 428 429 //-------------------------------------------------------------------- 430 bool MigrationLog::movedAnyLibrary( const DocumentID _nDocID ) 431 { 432 DocumentLogs::const_iterator docPos = m_pData->aDocumentLogs.find( _nDocID ); 433 if ( docPos == m_pData->aDocumentLogs.end() ) 434 { 435 OSL_ENSURE( false, "MigrationLog::movedAnyLibrary: document is not known!" ); 436 return false; 437 } 438 return !docPos->second.aMovedLibraries.empty(); 439 } 440 441 //-------------------------------------------------------------------- 442 ::rtl::OUString MigrationLog::getCompleteLog() const 443 { 444 ::rtl::OUStringBuffer aBuffer; 445 446 if ( m_pData->sBackupLocation.getLength() ) 447 { 448 String sBackedUp( MacroMigrationResId( STR_SAVED_COPY_TO ) ); 449 sBackedUp.SearchAndReplaceAllAscii( "$location$", m_pData->sBackupLocation ); 450 451 aBuffer.appendAscii( "=== " ); 452 aBuffer.append ( String( MacroMigrationResId( STR_DATABASE_DOCUMENT ) ) ); 453 aBuffer.appendAscii( " ===\n" ); 454 aBuffer.append ( sBackedUp ); 455 aBuffer.appendAscii( "\n\n" ); 456 } 457 458 if ( !m_pData->aFailures.empty() ) 459 { 460 lcl_describeErrors( aBuffer, m_pData->aFailures 461 , STR_ERRORS ); 462 } 463 else 464 { 465 String sMovedLibTemplate( MacroMigrationResId( STR_MOVED_LIBRARY ) ); 466 467 for ( DocumentLogs::const_iterator doc = m_pData->aDocumentLogs.begin(); 468 doc != m_pData->aDocumentLogs.end(); 469 ++doc 470 ) 471 { 472 const DocumentEntry& rDoc( doc->second ); 473 474 if ( rDoc.aMovedLibraries.empty() ) 475 continue; 476 477 String sDocTitle( MacroMigrationResId( rDoc.eType == eForm ? STR_FORM : STR_REPORT ) ); 478 sDocTitle.SearchAndReplaceAllAscii( "$name$", rDoc.sName ); 479 480 aBuffer.appendAscii( "=== " ); 481 aBuffer.append ( sDocTitle ); 482 aBuffer.appendAscii( " ===\n" ); 483 484 for ( ::std::vector< LibraryEntry >::const_iterator lib = rDoc.aMovedLibraries.begin(); 485 lib != rDoc.aMovedLibraries.end(); 486 ++lib 487 ) 488 { 489 String sMovedLib( sMovedLibTemplate ); 490 sMovedLib.SearchAndReplaceAllAscii( "$type$", getScriptTypeDisplayName( lib->eType ) ); 491 sMovedLib.SearchAndReplaceAllAscii( "$old$", lib->sOldName ); 492 sMovedLib.SearchAndReplaceAllAscii( "$new$", lib->sNewName ); 493 494 aBuffer.append( sMovedLib ); 495 aBuffer.append( sal_Unicode( '\n' ) ); 496 } 497 498 aBuffer.append( sal_Unicode( '\n' ) ); 499 } 500 } 501 502 if ( !m_pData->aWarnings.empty() ) 503 { 504 lcl_describeErrors( aBuffer, m_pData->aWarnings, STR_WARNINGS ); 505 } 506 507 return aBuffer.makeStringAndClear(); 508 } 509 510 //........................................................................ 511 } // namespace dbmm 512 //........................................................................ 513