blob: fe35489e7f5d34e26ffa5a5b73b2937b0fcff262 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"
#include "updatecheckconfig.hxx"
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertyState.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <osl/security.hxx>
#include <osl/time.h>
#include <osl/file.hxx>
#ifdef WNT
#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#pragma warning(disable: 4917)
#endif
#include <shlobj.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif
namespace container = com::sun::star::container ;
namespace beans = com::sun::star::beans ;
namespace lang = com::sun::star::lang ;
namespace util = com::sun::star::util ;
namespace uno = com::sun::star::uno ;
#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
#define LAST_CHECK "LastCheck"
#define VERSION_FOUND "UpdateVersionFound"
#define UPDATE_VERSION "UpdateVersion"
#define UPDATE_BUILDID "UpdateBuildId"
#define UPDATE_DESCRIPTION "UpdateDescription"
#define DOWNLOAD_URL "DownloadURL"
#define IS_DIRECT_DOWNLOAD "IsDirectDownload"
#define OLD_VERSION "UpdateFoundFor"
#define AUTOCHECK_ENABLED "AutoCheckEnabled"
#define AUTODOWNLOAD_ENABLED "AutoDownloadEnabled"
#define CHECK_INTERVAL "CheckInterval"
#define LOCAL_FILE "LocalFile"
#define DOWNLOAD_SIZE "DownloadSize"
#define DOWNLOAD_PAUSED "DownloadPaused"
#define DOWNLOAD_DESTINATION "DownloadDestination"
#define RELEASE_NOTE "ReleaseNote"
#define EXTENSION_PREFIX "Extension_"
#define PROPERTY_VERSION UNISTRING("Version")
static const sal_Char * const aUpdateEntryProperties[] = {
UPDATE_VERSION,
UPDATE_BUILDID,
UPDATE_DESCRIPTION,
DOWNLOAD_URL,
IS_DIRECT_DOWNLOAD,
RELEASE_NOTE"1",
RELEASE_NOTE"2",
RELEASE_NOTE"3",
RELEASE_NOTE"4",
RELEASE_NOTE"5",
OLD_VERSION
};
static const sal_uInt32 nUpdateEntryProperties = sizeof(aUpdateEntryProperties) / sizeof(sal_Char *);
//------------------------------------------------------------------------------
NamedValueByNameAccess::~NamedValueByNameAccess()
{
}
//------------------------------------------------------------------------------
::com::sun::star::uno::Any
NamedValueByNameAccess::getValue(const sal_Char * pName)
{
const sal_Int32 nLen = m_rValues.getLength();
for( sal_Int32 n=0; n < nLen; ++n )
{
if( m_rValues[n].Name.equalsAscii( pName ) )
return m_rValues[n].Value;
}
return ::com::sun::star::uno::Any();
}
//------------------------------------------------------------------------------
bool
UpdateCheckROModel::isAutoCheckEnabled() const
{
return sal_True == m_aNameAccess.getValue(AUTOCHECK_ENABLED).get< sal_Bool >();
}
//------------------------------------------------------------------------------
bool
UpdateCheckROModel::isDownloadPaused() const
{
return sal_True == m_aNameAccess.getValue(DOWNLOAD_PAUSED).get< sal_Bool >();
}
//------------------------------------------------------------------------------
rtl::OUString
UpdateCheckROModel::getStringValue(const sal_Char * pStr) const
{
uno::Any aAny( m_aNameAccess.getValue(pStr) );
rtl::OUString aRet;
aAny >>= aRet;
return aRet;
}
//------------------------------------------------------------------------------
rtl::OUString UpdateCheckROModel::getLocalFileName() const
{
return getStringValue(LOCAL_FILE);
};
//------------------------------------------------------------------------------
sal_Int64 UpdateCheckROModel::getDownloadSize() const
{
uno::Any aAny( m_aNameAccess.getValue(DOWNLOAD_SIZE) );
sal_Int64 nRet = -1;
aAny >>= nRet;
return nRet;
};
//------------------------------------------------------------------------------
rtl::OUString
UpdateCheckROModel::getUpdateEntryVersion() const
{
return getStringValue(OLD_VERSION);
}
//------------------------------------------------------------------------------
void
UpdateCheckROModel::getUpdateEntry(UpdateInfo& rInfo) const
{
rInfo.BuildId = getStringValue(UPDATE_BUILDID);
rInfo.Version = getStringValue(UPDATE_VERSION);
rInfo.Description = getStringValue(UPDATE_DESCRIPTION);
sal_Bool isDirectDownload = sal_False;
m_aNameAccess.getValue(IS_DIRECT_DOWNLOAD) >>= isDirectDownload;
rInfo.Sources.push_back( DownloadSource( isDirectDownload, getStringValue(DOWNLOAD_URL) ) );
rtl::OString aStr(RELEASE_NOTE);
for(sal_Int32 n=1; n < 6; ++n )
{
rtl::OUString aUStr = getStringValue( (aStr + rtl::OString::valueOf(n)).getStr());
if( aUStr.getLength() > 0 )
rInfo.ReleaseNotes.push_back(ReleaseNote((sal_Int8) n, aUStr));
}
}
//------------------------------------------------------------------------------
rtl::OUString UpdateCheckConfig::getDesktopDirectory()
{
rtl::OUString aRet;
#ifdef WNT
WCHAR szPath[MAX_PATH];
if( ! FAILED( SHGetSpecialFolderPathW( NULL, szPath, CSIDL_DESKTOPDIRECTORY, true ) ) )
{
aRet = rtl::OUString( reinterpret_cast< sal_Unicode * >(szPath) );
osl::FileBase::getFileURLFromSystemPath( aRet, aRet );
}
#else
// This should become a desktop specific setting in some system backend ..
rtl::OUString aHomeDir;
osl::Security().getHomeDir( aHomeDir );
aRet = aHomeDir + rtl::OUString::createFromAscii("/Desktop");
// Set path to home directory when there is no /Desktop directory
osl::Directory aDocumentsDir( aRet );
if( osl::FileBase::E_None != aDocumentsDir.open() )
aRet = aHomeDir;
#endif
return aRet;
}
//------------------------------------------------------------------------------
rtl::OUString UpdateCheckConfig::getAllUsersDirectory()
{
rtl::OUString aRet;
#ifdef WNT
WCHAR szPath[MAX_PATH];
if( ! FAILED( SHGetSpecialFolderPathW( NULL, szPath, CSIDL_COMMON_DOCUMENTS, true ) ) )
{
aRet = rtl::OUString( reinterpret_cast< sal_Unicode * >(szPath) );
osl::FileBase::RC rc;
rc = osl::FileBase::getFileURLFromSystemPath( aRet, aRet );
}
#else
osl::FileBase::getTempDirURL(aRet);
#endif
return aRet;
}
//------------------------------------------------------------------------------
UpdateCheckConfig::UpdateCheckConfig( const uno::Reference<container::XNameContainer>& xContainer,
const uno::Reference<container::XNameContainer>& xAvailableUpdates,
const uno::Reference<container::XNameContainer>& xIgnoredUpdates,
const ::rtl::Reference< UpdateCheckConfigListener >& rListener ) :
m_xContainer( xContainer ),
m_xAvailableUpdates( xAvailableUpdates ),
m_xIgnoredUpdates( xIgnoredUpdates ),
m_rListener( rListener )
{}
//------------------------------------------------------------------------------
UpdateCheckConfig::~UpdateCheckConfig()
{}
//------------------------------------------------------------------------------
::rtl::Reference< UpdateCheckConfig >
UpdateCheckConfig::get(
const uno::Reference<uno::XComponentContext>& xContext,
const ::rtl::Reference< UpdateCheckConfigListener >& rListener)
{
if( !xContext.is() )
throw uno::RuntimeException(
UNISTRING( "UpdateCheckConfig: empty component context" ),
uno::Reference< uno::XInterface >() );
uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
if( !xServiceManager.is() )
throw uno::RuntimeException(
UNISTRING( "UpdateCheckConfig: unable to obtain service manager from component context" ),
uno::Reference< uno::XInterface >() );
uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.configuration.ConfigurationProvider" ), xContext ),
uno::UNO_QUERY_THROW);
beans::PropertyValue aProperty;
aProperty.Name = UNISTRING( "nodepath" );
aProperty.Value = uno::makeAny( UNISTRING("org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments") );
uno::Sequence< uno::Any > aArgumentList( 1 );
aArgumentList[0] = uno::makeAny( aProperty );
uno::Reference< container::XNameContainer > xContainer(
xConfigProvider->createInstanceWithArguments(
UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ),
uno::UNO_QUERY_THROW );
aProperty.Value = uno::makeAny( UNISTRING("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/IgnoredUpdates") );
aArgumentList[0] = uno::makeAny( aProperty );
uno::Reference< container::XNameContainer > xIgnoredExt( xConfigProvider->createInstanceWithArguments( UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ), uno::UNO_QUERY_THROW );
aProperty.Value = uno::makeAny( UNISTRING("/org.openoffice.Office.ExtensionManager/ExtensionUpdateData/AvailableUpdates") );
aArgumentList[0] = uno::makeAny( aProperty );
uno::Reference< container::XNameContainer > xUpdateAvail( xConfigProvider->createInstanceWithArguments( UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"), aArgumentList ), uno::UNO_QUERY_THROW );
return new UpdateCheckConfig( xContainer, xUpdateAvail, xIgnoredExt, rListener );
}
//------------------------------------------------------------------------------
bool
UpdateCheckConfig::isAutoCheckEnabled() const
{
sal_Bool nValue = sal_False;
const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( AUTOCHECK_ENABLED ) ) >>= nValue;
return nValue;
}
//------------------------------------------------------------------------------
bool
UpdateCheckConfig::isAutoDownloadEnabled() const
{
sal_Bool nValue = sal_False;
const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( AUTODOWNLOAD_ENABLED ) ) >>= nValue;
return nValue;
}
//------------------------------------------------------------------------------
rtl::OUString
UpdateCheckConfig::getUpdateEntryVersion() const
{
rtl::OUString aValue;
// getByName is defined as non const in XNameAccess
const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( OLD_VERSION ) ) >>= aValue;
return aValue;
}
//------------------------------------------------------------------------------
sal_Int64
UpdateCheckConfig::getLastChecked() const
{
sal_Int64 nValue = 0;
// getByName is defined as non const in XNameAccess
const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( LAST_CHECK ) ) >>= nValue;
return nValue;
}
//------------------------------------------------------------------------------
sal_Int64
UpdateCheckConfig::getCheckInterval() const
{
sal_Int64 nValue = 0;
// getByName is defined as non const in XNameAccess
const_cast < UpdateCheckConfig *> (this)->getByName( UNISTRING( CHECK_INTERVAL ) ) >>= nValue;
return nValue;
}
//------------------------------------------------------------------------------
rtl::OUString
UpdateCheckConfig::getLocalFileName() const
{
rtl::OUString aName = UNISTRING(LOCAL_FILE);
rtl::OUString aRet;
if( m_xContainer->hasByName(aName) )
m_xContainer->getByName(aName) >>= aRet;
return aRet;
}
//------------------------------------------------------------------------------
rtl::OUString
UpdateCheckConfig::getDownloadDestination() const
{
rtl::OUString aName = UNISTRING(DOWNLOAD_DESTINATION);
rtl::OUString aRet;
const_cast <UpdateCheckConfig *> (this)->getByName(aName) >>= aRet;
return aRet;
}
//------------------------------------------------------------------------------
void
UpdateCheckConfig::storeLocalFileName(const rtl::OUString& rLocalFileName, sal_Int64 nFileSize)
{
const sal_uInt8 nItems = 2;
const rtl::OUString aNameList[nItems] = { UNISTRING(LOCAL_FILE), UNISTRING(DOWNLOAD_SIZE) };
const uno::Any aValueList[nItems] = { uno::makeAny(rLocalFileName), uno::makeAny(nFileSize) };
for( sal_uInt8 i=0; i < nItems; ++i )
{
if( m_xContainer->hasByName(aNameList[i]) )
m_xContainer->replaceByName(aNameList[i], aValueList[i]);
else
m_xContainer->insertByName(aNameList[i], aValueList[i]);
}
commitChanges();
}
//------------------------------------------------------------------------------
void
UpdateCheckConfig::clearLocalFileName()
{
const sal_uInt8 nItems = 2;
const rtl::OUString aNameList[nItems] = { UNISTRING(LOCAL_FILE), UNISTRING(DOWNLOAD_SIZE) };
for( sal_uInt8 i=0; i < nItems; ++i )
{
if( m_xContainer->hasByName(aNameList[i]) )
m_xContainer->removeByName(aNameList[i]);
}
commitChanges();
}
//------------------------------------------------------------------------------
void
UpdateCheckConfig::storeDownloadPaused(bool paused)
{
replaceByName(UNISTRING(DOWNLOAD_PAUSED) , uno::makeAny(paused));
commitChanges();
}
//------------------------------------------------------------------------------
void
UpdateCheckConfig::updateLastChecked()
{
TimeValue systime;
osl_getSystemTime(&systime);
sal_Int64 lastCheck = systime.Seconds;
replaceByName(UNISTRING(LAST_CHECK), uno::makeAny(lastCheck));
}
//------------------------------------------------------------------------------
void
UpdateCheckConfig::storeUpdateFound( const UpdateInfo& rInfo, const rtl::OUString& aCurrentBuild)
{
bool autoDownloadEnabled = isAutoDownloadEnabled();
uno::Any aValues[nUpdateEntryProperties] =
{
uno::makeAny(rInfo.Version),
uno::makeAny(rInfo.BuildId),
uno::makeAny(rInfo.Description),
uno::makeAny(rInfo.Sources[0].URL),
uno::makeAny(rInfo.Sources[0].IsDirect ? sal_True : sal_False),
uno::makeAny(getReleaseNote(rInfo, 1, autoDownloadEnabled) ),
uno::makeAny(getReleaseNote(rInfo, 2, autoDownloadEnabled) ),
uno::makeAny(getReleaseNote(rInfo, 3, autoDownloadEnabled) ),
uno::makeAny(getReleaseNote(rInfo, 4, autoDownloadEnabled) ),
uno::makeAny(getReleaseNote(rInfo, 5, autoDownloadEnabled) ),
uno::makeAny(aCurrentBuild)
};
rtl::OUString aName;
for( sal_uInt32 n=0; n < nUpdateEntryProperties; ++n )
{
aName = rtl::OUString::createFromAscii(aUpdateEntryProperties[n]);
if( m_xContainer->hasByName(aName) )
m_xContainer->replaceByName(aName, aValues[n]);
else
m_xContainer->insertByName(aName,aValues[n]);
}
commitChanges();
}
//------------------------------------------------------------------------------
void
UpdateCheckConfig::clearUpdateFound()
{
rtl::OUString aName;
for( sal_uInt32 n=0; n < nUpdateEntryProperties; ++n )
{
aName = rtl::OUString::createFromAscii(aUpdateEntryProperties[n]);
try {
if( m_xContainer->hasByName(aName) )
m_xContainer->removeByName(aName);
} catch(const lang::WrappedTargetException& ) {
// Can not remove value, probably in share layer
OSL_ASSERT(false);
m_xContainer->replaceByName(aName, uno::makeAny(rtl::OUString()));
}
}
/* As we have removed UpdateVersionFound from the shared configuration
* existing entries in the user layer do not have a oor operation and
* thus are completly ignored (which also means they can not be removed).
*/
commitChanges();
}
//------------------------------------------------------------------------------
uno::Sequence< rtl::OUString >
UpdateCheckConfig::getServiceNames()
{
uno::Sequence< rtl::OUString > aServiceList(1);
aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheckConfig");
return aServiceList;
}
//------------------------------------------------------------------------------
rtl::OUString
UpdateCheckConfig::getImplName()
{
return UNISTRING( "vnd.sun.UpdateCheckConfig");
}
//------------------------------------------------------------------------------
uno::Type SAL_CALL
UpdateCheckConfig::getElementType() throw (uno::RuntimeException)
{
return m_xContainer->getElementType();
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL
UpdateCheckConfig::hasElements() throw (uno::RuntimeException)
{
return m_xContainer->hasElements();
}
//------------------------------------------------------------------------------
uno::Any SAL_CALL
UpdateCheckConfig::getByName( const ::rtl::OUString& aName )
throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
{
uno::Any aValue = m_xContainer->getByName( aName );
// Provide dynamic default value
if( aName.equalsAscii(DOWNLOAD_DESTINATION) )
{
rtl::OUString aStr;
aValue >>= aStr;
if( aStr.getLength() == 0 )
aValue = uno::makeAny(getDesktopDirectory());
}
return aValue;
}
//------------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL
UpdateCheckConfig::getElementNames( ) throw (uno::RuntimeException)
{
return m_xContainer->getElementNames();
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL
UpdateCheckConfig::hasByName( const ::rtl::OUString& aName ) throw (uno::RuntimeException)
{
return m_xContainer->hasByName( aName );
}
//------------------------------------------------------------------------------
void SAL_CALL
UpdateCheckConfig::replaceByName( const ::rtl::OUString& aName, const uno::Any& aElement )
throw (lang::IllegalArgumentException, container::NoSuchElementException,
lang::WrappedTargetException, uno::RuntimeException)
{
return m_xContainer->replaceByName( aName, aElement );
}
//------------------------------------------------------------------------------
// XChangesBatch
void SAL_CALL
UpdateCheckConfig::commitChanges()
throw (lang::WrappedTargetException, uno::RuntimeException)
{
uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY);
if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
{
util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges();
xChangesBatch->commitChanges();
if( m_rListener.is() )
{
const sal_Int32 nChanges = aChangesSet.getLength();
rtl::OUString aString;
for( sal_Int32 i=0; i<nChanges; ++i )
{
aChangesSet[i].Accessor >>= aString;
// FIXME: use non IgnoreAsciiCase version as soon as it becomes available
if( aString.endsWithIgnoreAsciiCaseAsciiL(AUTOCHECK_ENABLED "']", sizeof(AUTOCHECK_ENABLED)+1) )
{
sal_Bool bEnabled = sal_False;
aChangesSet[i].Element >>= bEnabled;
m_rListener->autoCheckStatusChanged(sal_True == bEnabled);
}
// FIXME: use non IgnoreAsciiCase version as soon as it becomes available
else if( aString.endsWithIgnoreAsciiCaseAsciiL(CHECK_INTERVAL "']", sizeof(CHECK_INTERVAL)+1) )
{
m_rListener->autoCheckIntervalChanged();
}
}
}
}
xChangesBatch = uno::Reference< util::XChangesBatch > ( m_xAvailableUpdates, uno::UNO_QUERY );
if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
{
util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges();
xChangesBatch->commitChanges();
}
xChangesBatch = uno::Reference< util::XChangesBatch > ( m_xIgnoredUpdates, uno::UNO_QUERY );
if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
{
util::ChangesSet aChangesSet = xChangesBatch->getPendingChanges();
xChangesBatch->commitChanges();
}
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL
UpdateCheckConfig::hasPendingChanges( ) throw (uno::RuntimeException)
{
uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY);
if( xChangesBatch.is() )
return xChangesBatch->hasPendingChanges();
return sal_False;
}
//------------------------------------------------------------------------------
uno::Sequence< util::ElementChange > SAL_CALL
UpdateCheckConfig::getPendingChanges( ) throw (uno::RuntimeException)
{
uno::Reference< util::XChangesBatch > xChangesBatch(m_xContainer, uno::UNO_QUERY);
if( xChangesBatch.is() )
return xChangesBatch->getPendingChanges();
return uno::Sequence< util::ElementChange >();
}
//------------------------------------------------------------------------------
bool UpdateCheckConfig::storeExtensionVersion( const rtl::OUString& rExtensionName,
const rtl::OUString& rVersion )
{
bool bNotify = true;
if ( m_xAvailableUpdates->hasByName( rExtensionName ) )
uno::Reference< beans::XPropertySet >( m_xAvailableUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->setPropertyValue( PROPERTY_VERSION, uno::Any( rVersion ) );
else
{
uno::Reference< beans::XPropertySet > elem( uno::Reference< lang::XSingleServiceFactory >( m_xAvailableUpdates, uno::UNO_QUERY_THROW )->createInstance(), uno::UNO_QUERY_THROW );
elem->setPropertyValue( PROPERTY_VERSION, uno::Any( rVersion ) );
m_xAvailableUpdates->insertByName( rExtensionName, uno::Any( elem ) );
}
if ( m_xIgnoredUpdates->hasByName( rExtensionName ) )
{
::rtl::OUString aIgnoredVersion;
uno::Any aValue( uno::Reference< beans::XPropertySet >( m_xIgnoredUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
aValue >>= aIgnoredVersion;
if ( aIgnoredVersion.getLength() == 0 ) // no version means ignore all updates
bNotify = false;
else if ( aIgnoredVersion == rVersion ) // the user wanted to ignore this update
bNotify = false;
}
commitChanges();
return bNotify;
}
//------------------------------------------------------------------------------
bool UpdateCheckConfig::checkExtensionVersion( const rtl::OUString& rExtensionName,
const rtl::OUString& rVersion )
{
if ( m_xAvailableUpdates->hasByName( rExtensionName ) )
{
::rtl::OUString aStoredVersion;
uno::Any aValue( uno::Reference< beans::XPropertySet >( m_xAvailableUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
aValue >>= aStoredVersion;
if ( m_xIgnoredUpdates->hasByName( rExtensionName ) )
{
::rtl::OUString aIgnoredVersion;
uno::Any aValue2( uno::Reference< beans::XPropertySet >( m_xIgnoredUpdates->getByName( rExtensionName ), uno::UNO_QUERY_THROW )->getPropertyValue( PROPERTY_VERSION ) );
aValue2 >>= aIgnoredVersion;
if ( aIgnoredVersion.getLength() == 0 ) // no version means ignore all updates
return false;
else if ( aIgnoredVersion == aStoredVersion ) // the user wanted to ignore this update
return false;
// TODO: else delete ignored entry?
}
if ( isVersionGreater( rVersion, aStoredVersion ) )
return true;
else
{
m_xAvailableUpdates->removeByName( rExtensionName );
commitChanges();
}
}
return false;
}
//------------------------------------------------------------------------------
rtl::OUString UpdateCheckConfig::getSubVersion( const rtl::OUString& rVersion,
sal_Int32 *nIndex )
{
while ( *nIndex < rVersion.getLength() && rVersion[*nIndex] == '0')
{
++*nIndex;
}
return rVersion.getToken( 0, '.', *nIndex );
}
//------------------------------------------------------------------------------
// checks if the second version string is greater than the first one
bool UpdateCheckConfig::isVersionGreater( const rtl::OUString& rVersion1,
const rtl::OUString& rVersion2 )
{
for ( sal_Int32 i1 = 0, i2 = 0; i1 >= 0 || i2 >= 0; )
{
::rtl::OUString sSub1( getSubVersion( rVersion1, &i1 ) );
::rtl::OUString sSub2( getSubVersion( rVersion2, &i2 ) );
if ( sSub1.getLength() < sSub2.getLength() ) {
return true;
} else if ( sSub1.getLength() > sSub2.getLength() ) {
return false;
} else if ( sSub1 < sSub2 ) {
return true;
} else if ( sSub1 > sSub2 ) {
return false;
}
}
return false;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
rtl::OUString SAL_CALL
UpdateCheckConfig::getImplementationName() throw (uno::RuntimeException)
{
return getImplName();
}
//------------------------------------------------------------------------------
sal_Bool SAL_CALL
UpdateCheckConfig::supportsService(rtl::OUString const & serviceName)
throw (uno::RuntimeException)
{
uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames();
for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
if( aServiceNameList[n].equals(serviceName) )
return sal_True;
return sal_False;
}
//------------------------------------------------------------------------------
uno::Sequence< rtl::OUString > SAL_CALL
UpdateCheckConfig::getSupportedServiceNames() throw (uno::RuntimeException)
{
return getServiceNames();
}