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