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_extensions.hxx" 26 27 28 #include "updatecheckconfig.hxx" 29 #include <com/sun/star/beans/PropertyValue.hpp> 30 #include <com/sun/star/beans/XPropertyState.hpp> 31 #include <com/sun/star/beans/XPropertySet.hpp> 32 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 33 34 #include <osl/security.hxx> 35 #include <osl/time.h> 36 #include <osl/file.hxx> 37 38 #ifdef WNT 39 #ifdef _MSC_VER 40 #pragma warning(push,1) // disable warnings within system headers 41 #pragma warning(disable: 4917) 42 #endif 43 #include <shlobj.h> 44 #ifdef _MSC_VER 45 #pragma warning(pop) 46 #endif 47 #endif 48 49 namespace container = com::sun::star::container ; 50 namespace beans = com::sun::star::beans ; 51 namespace lang = com::sun::star::lang ; 52 namespace util = com::sun::star::util ; 53 namespace uno = com::sun::star::uno ; 54 55 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 56 57 #define LAST_CHECK "LastCheck" 58 #define VERSION_FOUND "UpdateVersionFound" 59 #define UPDATE_VERSION "UpdateVersion" 60 #define UPDATE_BUILDID "UpdateBuildId" 61 #define UPDATE_DESCRIPTION "UpdateDescription" 62 #define DOWNLOAD_URL "DownloadURL" 63 #define IS_DIRECT_DOWNLOAD "IsDirectDownload" 64 #define OLD_VERSION "UpdateFoundFor" 65 #define AUTOCHECK_ENABLED "AutoCheckEnabled" 66 #define AUTODOWNLOAD_ENABLED "AutoDownloadEnabled" 67 #define CHECK_INTERVAL "CheckInterval" 68 #define LOCAL_FILE "LocalFile" 69 #define DOWNLOAD_SIZE "DownloadSize" 70 #define DOWNLOAD_PAUSED "DownloadPaused" 71 #define DOWNLOAD_DESTINATION "DownloadDestination" 72 #define RELEASE_NOTE "ReleaseNote" 73 #define EXTENSION_PREFIX "Extension_" 74 75 #define PROPERTY_VERSION UNISTRING("Version") 76 77 static const sal_Char * const aUpdateEntryProperties[] = { 78 UPDATE_VERSION, 79 UPDATE_BUILDID, 80 UPDATE_DESCRIPTION, 81 DOWNLOAD_URL, 82 IS_DIRECT_DOWNLOAD, 83 RELEASE_NOTE"1", 84 RELEASE_NOTE"2", 85 RELEASE_NOTE"3", 86 RELEASE_NOTE"4", 87 RELEASE_NOTE"5", 88 OLD_VERSION 89 }; 90 91 static const sal_uInt32 nUpdateEntryProperties = sizeof(aUpdateEntryProperties) / sizeof(sal_Char *); 92 93 //------------------------------------------------------------------------------ 94 95 NamedValueByNameAccess::~NamedValueByNameAccess() 96 { 97 } 98 99 //------------------------------------------------------------------------------ 100 101 ::com::sun::star::uno::Any 102 NamedValueByNameAccess::getValue(const sal_Char * pName) 103 { 104 const sal_Int32 nLen = m_rValues.getLength(); 105 for( sal_Int32 n=0; n < nLen; ++n ) 106 { 107 if( m_rValues[n].Name.equalsAscii( pName ) ) 108 return m_rValues[n].Value; 109 } 110 return ::com::sun::star::uno::Any(); 111 } 112 113 114 //------------------------------------------------------------------------------ 115 116 bool 117 UpdateCheckROModel::isAutoCheckEnabled() const 118 { 119 return sal_True == m_aNameAccess.getValue(AUTOCHECK_ENABLED).get< sal_Bool >(); 120 } 121 122 //------------------------------------------------------------------------------ 123 124 bool 125 UpdateCheckROModel::isDownloadPaused() const 126 { 127 return sal_True == m_aNameAccess.getValue(DOWNLOAD_PAUSED).get< sal_Bool >(); 128 } 129 130 //------------------------------------------------------------------------------ 131 132 rtl::OUString 133 UpdateCheckROModel::getStringValue(const sal_Char * pStr) const 134 { 135 uno::Any aAny( m_aNameAccess.getValue(pStr) ); 136 rtl::OUString aRet; 137 138 aAny >>= aRet; 139 140 return aRet; 141 } 142 143 //------------------------------------------------------------------------------ 144 145 rtl::OUString UpdateCheckROModel::getLocalFileName() const 146 { 147 return getStringValue(LOCAL_FILE); 148 }; 149 150 //------------------------------------------------------------------------------ 151 152 sal_Int64 UpdateCheckROModel::getDownloadSize() const 153 { 154 uno::Any aAny( m_aNameAccess.getValue(DOWNLOAD_SIZE) ); 155 sal_Int64 nRet = -1; 156 157 aAny >>= nRet; 158 return nRet; 159 }; 160 161 //------------------------------------------------------------------------------ 162 163 rtl::OUString 164 UpdateCheckROModel::getUpdateEntryVersion() const 165 { 166 return getStringValue(OLD_VERSION); 167 } 168 169 //------------------------------------------------------------------------------ 170 171 void 172 UpdateCheckROModel::getUpdateEntry(UpdateInfo& rInfo) const 173 { 174 rInfo.BuildId = getStringValue(UPDATE_BUILDID); 175 rInfo.Version = getStringValue(UPDATE_VERSION); 176 rInfo.Description = getStringValue(UPDATE_DESCRIPTION); 177 178 sal_Bool isDirectDownload = sal_False; 179 m_aNameAccess.getValue(IS_DIRECT_DOWNLOAD) >>= isDirectDownload; 180 181 rInfo.Sources.push_back( DownloadSource( isDirectDownload, getStringValue(DOWNLOAD_URL) ) ); 182 183 rtl::OString aStr(RELEASE_NOTE); 184 for(sal_Int32 n=1; n < 6; ++n ) 185 { 186 rtl::OUString aUStr = getStringValue(aStr + rtl::OString::valueOf(n)); 187 if( aUStr.getLength() > 0 ) 188 rInfo.ReleaseNotes.push_back(ReleaseNote((sal_Int8) n, aUStr)); 189 } 190 } 191 192 193 //------------------------------------------------------------------------------ 194 195 rtl::OUString UpdateCheckConfig::getDesktopDirectory() 196 { 197 rtl::OUString aRet; 198 199 #ifdef WNT 200 WCHAR szPath[MAX_PATH]; 201 202 if( ! FAILED( SHGetSpecialFolderPathW( NULL, szPath, CSIDL_DESKTOPDIRECTORY, true ) ) ) 203 { 204 aRet = rtl::OUString( reinterpret_cast< sal_Unicode * >(szPath) ); 205 osl::FileBase::getFileURLFromSystemPath( aRet, aRet ); 206 } 207 #else 208 // This should become a desktop specific setting in some system backend .. 209 rtl::OUString aHomeDir; 210 osl::Security().getHomeDir( aHomeDir ); 211 aRet = aHomeDir + rtl::OUString::createFromAscii("/Desktop"); 212 213 // Set path to home directory when there is no /Desktop directory 214 osl::Directory aDocumentsDir( aRet ); 215 if( osl::FileBase::E_None != aDocumentsDir.open() ) 216 aRet = aHomeDir; 217 #endif 218 219 return aRet; 220 } 221 222 //------------------------------------------------------------------------------ 223 224 rtl::OUString UpdateCheckConfig::getAllUsersDirectory() 225 { 226 rtl::OUString aRet; 227 228 #ifdef WNT 229 WCHAR szPath[MAX_PATH]; 230 231 if( ! FAILED( SHGetSpecialFolderPathW( NULL, szPath, CSIDL_COMMON_DOCUMENTS, true ) ) ) 232 { 233 aRet = rtl::OUString( reinterpret_cast< sal_Unicode * >(szPath) ); 234 osl::FileBase::RC rc; 235 rc = osl::FileBase::getFileURLFromSystemPath( aRet, aRet ); 236 } 237 #else 238 osl::FileBase::getTempDirURL(aRet); 239 #endif 240 241 return aRet; 242 } 243 244 //------------------------------------------------------------------------------ 245 UpdateCheckConfig::UpdateCheckConfig( const uno::Reference<container::XNameContainer>& xContainer, 246 const uno::Reference<container::XNameContainer>& xAvailableUpdates, 247 const uno::Reference<container::XNameContainer>& xIgnoredUpdates, 248 const ::rtl::Reference< UpdateCheckConfigListener >& rListener ) : 249 m_xContainer( xContainer ), 250 m_xAvailableUpdates( xAvailableUpdates ), 251 m_xIgnoredUpdates( xIgnoredUpdates ), 252 m_rListener( rListener ) 253 {} 254 255 //------------------------------------------------------------------------------ 256 UpdateCheckConfig::~UpdateCheckConfig() 257 {} 258 259 //------------------------------------------------------------------------------ 260 261 ::rtl::Reference< UpdateCheckConfig > 262 UpdateCheckConfig::get( 263 const uno::Reference<uno::XComponentContext>& xContext, 264 const ::rtl::Reference< UpdateCheckConfigListener >& rListener) 265 { 266 if( !xContext.is() ) 267 throw uno::RuntimeException( 268 UNISTRING( "UpdateCheckConfig: empty component context" ), 269 uno::Reference< uno::XInterface >() ); 270 271 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager()); 272 273 if( !xServiceManager.is() ) 274 throw uno::RuntimeException( 275 UNISTRING( "UpdateCheckConfig: unable to obtain service manager from component context" ), 276 uno::Reference< uno::XInterface >() ); 277 278 uno::Reference< lang::XMultiServiceFactory > xConfigProvider( 279 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.configuration.ConfigurationProvider" ), xContext ), 280 uno::UNO_QUERY_THROW); 281 282 beans::PropertyValue aProperty; 283 aProperty.Name = UNISTRING( "nodepath" ); 284 aProperty.Value = uno::makeAny( UNISTRING("org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments") ); 285 286 uno::Sequence< uno::Any > aArgumentList( 1 ); 287 aArgumentList[0] = uno::makeAny( aProperty ); 288 289 uno::Reference< container::XNameContainer > xContainer( 290 xConfigProvider->createInstanceWithArguments( 291 UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ), 292 uno::UNO_QUERY_THROW ); 293 294 aProperty.Value = uno::makeAny( UNISTRING("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/IgnoredUpdates") ); 295 aArgumentList[0] = uno::makeAny( aProperty ); 296 uno::Reference< container::XNameContainer > xIgnoredExt( xConfigProvider->createInstanceWithArguments( UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ), uno::UNO_QUERY_THROW ); 297 298 aProperty.Value = uno::makeAny( UNISTRING("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/AvailableUpdates") ); 299 aArgumentList[0] = uno::makeAny( aProperty ); 300 uno::Reference< container::XNameContainer > xUpdateAvail( xConfigProvider->createInstanceWithArguments( UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ), uno::UNO_QUERY_THROW ); 301 302 return new UpdateCheckConfig( xContainer, xUpdateAvail, xIgnoredExt, rListener ); 303 } 304 305 //------------------------------------------------------------------------------ 306 307 bool 308 UpdateCheckConfig::isAutoCheckEnabled() const 309 { 310 sal_Bool nValue = sal_False; 311 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( AUTOCHECK_ENABLED ) ) >>= nValue; 312 return nValue; 313 } 314 315 //------------------------------------------------------------------------------ 316 317 bool 318 UpdateCheckConfig::isAutoDownloadEnabled() const 319 { 320 sal_Bool nValue = sal_False; 321 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( AUTODOWNLOAD_ENABLED ) ) >>= nValue; 322 return nValue; 323 } 324 325 //------------------------------------------------------------------------------ 326 327 rtl::OUString 328 UpdateCheckConfig::getUpdateEntryVersion() const 329 { 330 rtl::OUString aValue; 331 332 // getByName is defined as non const in XNameAccess 333 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( OLD_VERSION ) ) >>= aValue; 334 335 return aValue; 336 } 337 338 //------------------------------------------------------------------------------ 339 340 sal_Int64 341 UpdateCheckConfig::getLastChecked() const 342 { 343 sal_Int64 nValue = 0; 344 345 // getByName is defined as non const in XNameAccess 346 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( LAST_CHECK ) ) >>= nValue; 347 348 return nValue; 349 } 350 351 //------------------------------------------------------------------------------ 352 353 sal_Int64 354 UpdateCheckConfig::getCheckInterval() const 355 { 356 sal_Int64 nValue = 0; 357 358 // getByName is defined as non const in XNameAccess 359 const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( CHECK_INTERVAL ) ) >>= nValue; 360 361 return nValue; 362 } 363 364 //------------------------------------------------------------------------------ 365 366 rtl::OUString 367 UpdateCheckConfig::getLocalFileName() const 368 { 369 rtl::OUString aName = UNISTRING(LOCAL_FILE); 370 rtl::OUString aRet; 371 372 if( m_xContainer->hasByName(aName) ) 373 m_xContainer->getByName(aName) >>= aRet; 374 375 return aRet; 376 } 377 378 //------------------------------------------------------------------------------ 379 380 rtl::OUString 381 UpdateCheckConfig::getDownloadDestination() const 382 { 383 rtl::OUString aName = UNISTRING(DOWNLOAD_DESTINATION); 384 rtl::OUString aRet; 385 386 const_cast <UpdateCheckConfig *> (this)->getByName(aName) >>= aRet; 387 388 return aRet; 389 } 390 391 //------------------------------------------------------------------------------ 392 393 void 394 UpdateCheckConfig::storeLocalFileName(const rtl::OUString& rLocalFileName, sal_Int64 nFileSize) 395 { 396 const sal_uInt8 nItems = 2; 397 const rtl::OUString aNameList[nItems] = { UNISTRING(LOCAL_FILE), UNISTRING(DOWNLOAD_SIZE) }; 398 const uno::Any aValueList[nItems] = { uno::makeAny(rLocalFileName), uno::makeAny(nFileSize) }; 399 400 for( sal_uInt8 i=0; i < nItems; ++i ) 401 { 402 if( m_xContainer->hasByName(aNameList[i]) ) 403 m_xContainer->replaceByName(aNameList[i], aValueList[i]); 404 else 405 m_xContainer->insertByName(aNameList[i], aValueList[i]); 406 } 407 408 commitChanges(); 409 } 410 411 //------------------------------------------------------------------------------ 412 413 void 414 UpdateCheckConfig::clearLocalFileName() 415 { 416 const sal_uInt8 nItems = 2; 417 const rtl::OUString aNameList[nItems] = { UNISTRING(LOCAL_FILE), UNISTRING(DOWNLOAD_SIZE) }; 418 419 for( sal_uInt8 i=0; i < nItems; ++i ) 420 { 421 if( m_xContainer->hasByName(aNameList[i]) ) 422 m_xContainer->removeByName(aNameList[i]); 423 } 424 425 commitChanges(); 426 } 427 428 //------------------------------------------------------------------------------ 429 430 void 431 UpdateCheckConfig::storeDownloadPaused(bool paused) 432 { 433 replaceByName(UNISTRING(DOWNLOAD_PAUSED) , uno::makeAny(paused)); 434 commitChanges(); 435 } 436 437 //------------------------------------------------------------------------------ 438 439 void 440 UpdateCheckConfig::updateLastChecked() 441 { 442 TimeValue systime; 443 osl_getSystemTime(&systime); 444 445 sal_Int64 lastCheck = systime.Seconds; 446 447 replaceByName(UNISTRING(LAST_CHECK), uno::makeAny(lastCheck)); 448 } 449 450 //------------------------------------------------------------------------------ 451 452 void 453 UpdateCheckConfig::storeUpdateFound( const UpdateInfo& rInfo, const rtl::OUString& aCurrentBuild) 454 455 { 456 bool autoDownloadEnabled = isAutoDownloadEnabled(); 457 458 uno::Any aValues[nUpdateEntryProperties] = 459 { 460 uno::makeAny(rInfo.Version), 461 uno::makeAny(rInfo.BuildId), 462 uno::makeAny(rInfo.Description), 463 uno::makeAny(rInfo.Sources[0].URL), 464 uno::makeAny(rInfo.Sources[0].IsDirect ? sal_True : sal_False), 465 uno::makeAny(getReleaseNote(rInfo, 1, autoDownloadEnabled) ), 466 uno::makeAny(getReleaseNote(rInfo, 2, autoDownloadEnabled) ), 467 uno::makeAny(getReleaseNote(rInfo, 3, autoDownloadEnabled) ), 468 uno::makeAny(getReleaseNote(rInfo, 4, autoDownloadEnabled) ), 469 uno::makeAny(getReleaseNote(rInfo, 5, autoDownloadEnabled) ), 470 uno::makeAny(aCurrentBuild) 471 }; 472 473 rtl::OUString aName; 474 for( sal_uInt32 n=0; n < nUpdateEntryProperties; ++n ) 475 { 476 aName = rtl::OUString::createFromAscii(aUpdateEntryProperties[n]); 477 478 if( m_xContainer->hasByName(aName) ) 479 m_xContainer->replaceByName(aName, aValues[n]); 480 else 481 m_xContainer->insertByName(aName,aValues[n]); 482 } 483 484 commitChanges(); 485 } 486 487 //------------------------------------------------------------------------------ 488 489 void 490 UpdateCheckConfig::clearUpdateFound() 491 { 492 rtl::OUString aName; 493 494 for( sal_uInt32 n=0; n < nUpdateEntryProperties; ++n ) 495 { 496 aName = rtl::OUString::createFromAscii(aUpdateEntryProperties[n]); 497 498 try { 499 if( m_xContainer->hasByName(aName) ) 500 m_xContainer->removeByName(aName); 501 } catch(const lang::WrappedTargetException& ) { 502 // Can not remove value, probably in share layer 503 OSL_ASSERT(false); 504 m_xContainer->replaceByName(aName, uno::makeAny(rtl::OUString())); 505 } 506 } 507 508 /* As we have removed UpdateVersionFound from the shared configuration 509 * existing entries in the user layer do not have a oor operation and 510 * thus are completly ignored (which also means they can not be removed). 511 */ 512 513 commitChanges(); 514 } 515 516 //------------------------------------------------------------------------------ 517 518 uno::Sequence< rtl::OUString > 519 UpdateCheckConfig::getServiceNames() 520 { 521 uno::Sequence< rtl::OUString > aServiceList(1); 522 aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheckConfig"); 523 return aServiceList; 524 } 525 526 //------------------------------------------------------------------------------ 527 528 rtl::OUString 529 UpdateCheckConfig::getImplName() 530 { 531 return UNISTRING( "vnd.sun.UpdateCheckConfig"); 532 } 533 534 //------------------------------------------------------------------------------ 535 536 uno::Type SAL_CALL 537 UpdateCheckConfig::getElementType() throw (uno::RuntimeException) 538 { 539 return m_xContainer->getElementType(); 540 } 541 542 //------------------------------------------------------------------------------ 543 544 sal_Bool SAL_CALL 545 UpdateCheckConfig::hasElements() throw (uno::RuntimeException) 546 { 547 return m_xContainer->hasElements(); 548 } 549 550 //------------------------------------------------------------------------------ 551 552 uno::Any SAL_CALL 553 UpdateCheckConfig::getByName( const ::rtl::OUString& aName ) 554 throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 555 { 556 uno::Any aValue = m_xContainer->getByName( aName ); 557 558 // Provide dynamic default value 559 if( aName.equalsAscii(DOWNLOAD_DESTINATION) ) 560 { 561 rtl::OUString aStr; 562 aValue >>= aStr; 563 564 if( aStr.getLength() == 0 ) 565 aValue = uno::makeAny(getDesktopDirectory()); 566 } 567 568 return aValue; 569 } 570 571 //------------------------------------------------------------------------------ 572 573 uno::Sequence< ::rtl::OUString > SAL_CALL 574 UpdateCheckConfig::getElementNames( ) throw (uno::RuntimeException) 575 { 576 return m_xContainer->getElementNames(); 577 } 578 579 //------------------------------------------------------------------------------ 580 581 sal_Bool SAL_CALL 582 UpdateCheckConfig::hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException) 583 { 584 return m_xContainer->hasByName( aName ); 585 } 586 587 //------------------------------------------------------------------------------ 588 589 void SAL_CALL 590 UpdateCheckConfig::replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement ) 591 throw (lang::IllegalArgumentException, container::NoSuchElementException, 592 lang::WrappedTargetException, uno::RuntimeException) 593 { 594 return m_xContainer->replaceByName( aName, aElement ); 595 } 596 597 //------------------------------------------------------------------------------ 598 // XChangesBatch 599 600 void SAL_CALL 601 UpdateCheckConfig::commitChanges() 602 throw (lang::WrappedTargetException, uno::RuntimeException) 603 { 604 uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY); 605 if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() ) 606 { 607 util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges(); 608 xChangesBatch->commitChanges(); 609 610 if( m_rListener.is() ) 611 { 612 const sal_Int32 nChanges = aChangesSet.getLength(); 613 rtl::OUString aString; 614 615 for( sal_Int32 i=0; i<nChanges; ++i ) 616 { 617 aChangesSet[i].Accessor >>= aString; 618 619 // FIXME: use non IgnoreAsciiCase version as soon as it becomes available 620 if( aString.endsWithIgnoreAsciiCaseAsciiL(AUTOCHECK_ENABLED "']", sizeof(AUTOCHECK_ENABLED)+1) ) 621 { 622 sal_Bool bEnabled = sal_False; 623 aChangesSet[i].Element >>= bEnabled; 624 m_rListener->autoCheckStatusChanged(sal_True == bEnabled); 625 } 626 // FIXME: use non IgnoreAsciiCase version as soon as it becomes available 627 else if( aString.endsWithIgnoreAsciiCaseAsciiL(CHECK_INTERVAL "']", sizeof(CHECK_INTERVAL)+1) ) 628 { 629 m_rListener->autoCheckIntervalChanged(); 630 } 631 } 632 } 633 } 634 635 xChangesBatch = uno::Reference< util::XChangesBatch > ( m_xAvailableUpdates, uno::UNO_QUERY ); 636 if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() ) 637 { 638 util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges(); 639 xChangesBatch->commitChanges(); 640 } 641 xChangesBatch = uno::Reference< util::XChangesBatch > ( m_xIgnoredUpdates, uno::UNO_QUERY ); 642 if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() ) 643 { 644 util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges(); 645 xChangesBatch->commitChanges(); 646 } 647 } 648 649 //------------------------------------------------------------------------------ 650 651 sal_Bool SAL_CALL 652 UpdateCheckConfig::hasPendingChanges( ) throw (uno::RuntimeException) 653 { 654 uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY); 655 if( xChangesBatch.is() ) 656 return xChangesBatch->hasPendingChanges(); 657 658 return sal_False; 659 } 660 661 //------------------------------------------------------------------------------ 662 663 uno::Sequence< util::ElementChange > SAL_CALL 664 UpdateCheckConfig::getPendingChanges( ) throw (uno::RuntimeException) 665 { 666 uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY); 667 if( xChangesBatch.is() ) 668 return xChangesBatch->getPendingChanges(); 669 670 return uno::Sequence< util::ElementChange >(); 671 } 672 673 //------------------------------------------------------------------------------ 674 bool UpdateCheckConfig::storeExtensionVersion( const rtl::OUString& rExtensionName, 675 const rtl::OUString& rVersion ) 676 { 677 bool bNotify = true; 678 679 if ( m_xAvailableUpdates->hasByName( rExtensionName ) ) 680 uno::Reference< beans::XPropertySet >( m_xAvailableUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->setPropertyValue( PROPERTY_VERSION, uno::Any( rVersion ) ); 681 else 682 { 683 uno::Reference< beans::XPropertySet > elem( uno::Reference< lang::XSingleServiceFactory >( m_xAvailableUpdates, uno::UNO_QUERY_THROW )->createInstance(), uno::UNO_QUERY_THROW ); 684 elem->setPropertyValue( PROPERTY_VERSION, uno::Any( rVersion ) ); 685 m_xAvailableUpdates->insertByName( rExtensionName, uno::Any( elem ) ); 686 } 687 688 if ( m_xIgnoredUpdates->hasByName( rExtensionName ) ) 689 { 690 ::rtl::OUString aIgnoredVersion; 691 uno::Any aValue( uno::Reference< beans::XPropertySet >( m_xIgnoredUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) ); 692 aValue >>= aIgnoredVersion; 693 if ( aIgnoredVersion.getLength() == 0 ) // no version means ignore all updates 694 bNotify = false; 695 else if ( aIgnoredVersion == rVersion ) // the user wanted to ignore this update 696 bNotify = false; 697 } 698 699 commitChanges(); 700 701 return bNotify; 702 } 703 704 //------------------------------------------------------------------------------ 705 bool UpdateCheckConfig::checkExtensionVersion( const rtl::OUString& rExtensionName, 706 const rtl::OUString& rVersion ) 707 { 708 if ( m_xAvailableUpdates->hasByName( rExtensionName ) ) 709 { 710 ::rtl::OUString aStoredVersion; 711 uno::Any aValue( uno::Reference< beans::XPropertySet >( m_xAvailableUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) ); 712 aValue >>= aStoredVersion; 713 714 if ( m_xIgnoredUpdates->hasByName( rExtensionName ) ) 715 { 716 ::rtl::OUString aIgnoredVersion; 717 uno::Any aValue2( uno::Reference< beans::XPropertySet >( m_xIgnoredUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) ); 718 aValue2 >>= aIgnoredVersion; 719 if ( aIgnoredVersion.getLength() == 0 ) // no version means ignore all updates 720 return false; 721 else if ( aIgnoredVersion == aStoredVersion ) // the user wanted to ignore this update 722 return false; 723 // TODO: else delete ignored entry? 724 } 725 if ( isVersionGreater( rVersion, aStoredVersion ) ) 726 return true; 727 else 728 { 729 m_xAvailableUpdates->removeByName( rExtensionName ); 730 commitChanges(); 731 } 732 } 733 734 return false; 735 } 736 737 //------------------------------------------------------------------------------ 738 rtl::OUString UpdateCheckConfig::getSubVersion( const rtl::OUString& rVersion, 739 sal_Int32 *nIndex ) 740 { 741 while ( *nIndex < rVersion.getLength() && rVersion[*nIndex] == '0') 742 { 743 ++*nIndex; 744 } 745 746 return rVersion.getToken( 0, '.', *nIndex ); 747 } 748 749 //------------------------------------------------------------------------------ 750 // checks if the second version string is greater than the first one 751 752 bool UpdateCheckConfig::isVersionGreater( const rtl::OUString& rVersion1, 753 const rtl::OUString& rVersion2 ) 754 { 755 for ( sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0; ) 756 { 757 ::rtl::OUString sSub1( getSubVersion( rVersion1, &i1 ) ); 758 ::rtl::OUString sSub2( getSubVersion( rVersion2, &i2 ) ); 759 760 if ( sSub1.getLength() < sSub2.getLength() ) { 761 return true; 762 } else if ( sSub1.getLength() > sSub2.getLength() ) { 763 return false; 764 } else if ( sSub1 < sSub2 ) { 765 return true; 766 } else if ( sSub1 > sSub2 ) { 767 return false; 768 } 769 } 770 return false; 771 } 772 773 //------------------------------------------------------------------------------ 774 //------------------------------------------------------------------------------ 775 //------------------------------------------------------------------------------ 776 777 rtl::OUString SAL_CALL 778 UpdateCheckConfig::getImplementationName() throw (uno::RuntimeException) 779 { 780 return getImplName(); 781 } 782 783 //------------------------------------------------------------------------------ 784 785 sal_Bool SAL_CALL 786 UpdateCheckConfig::supportsService(rtl::OUString const & serviceName) 787 throw (uno::RuntimeException) 788 { 789 uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames(); 790 791 for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ ) 792 if( aServiceNameList[n].equals(serviceName) ) 793 return sal_True; 794 795 return sal_False; 796 } 797 798 //------------------------------------------------------------------------------ 799 800 uno::Sequence< rtl::OUString > SAL_CALL 801 UpdateCheckConfig::getSupportedServiceNames() throw (uno::RuntimeException) 802 { 803 return getServiceNames(); 804 } 805 806 807