summaryrefslogtreecommitdiff
path: root/extensions/source/update/check/updatecheckconfig.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/source/update/check/updatecheckconfig.cxx')
-rw-r--r--extensions/source/update/check/updatecheckconfig.cxx763
1 files changed, 763 insertions, 0 deletions
diff --git a/extensions/source/update/check/updatecheckconfig.cxx b/extensions/source/update/check/updatecheckconfig.cxx
new file mode 100644
index 000000000000..881fe2572d67
--- /dev/null
+++ b/extensions/source/update/check/updatecheckconfig.cxx
@@ -0,0 +1,763 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 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/XPropertyState.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_"
+
+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));
+ 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 ::rtl::Reference< UpdateCheckConfigListener >& rListener
+) : m_xContainer(xContainer), 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 );
+
+ return new UpdateCheckConfig( xContainer, 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();
+ }
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+
+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 >();
+}
+
+//------------------------------------------------------------------------------
+void UpdateCheckConfig::storeExtensionVersion( const rtl::OUString& rExtensionName,
+ const rtl::OUString& rVersion )
+{
+ const rtl::OUString aExtName = UNISTRING( EXTENSION_PREFIX ) + rExtensionName;
+ const uno::Any aValue = uno::makeAny( rVersion );
+
+ if( m_xContainer->hasByName( aExtName ) )
+ m_xContainer->replaceByName( aExtName, aValue );
+ else
+ m_xContainer->insertByName( aExtName, aValue );
+
+ commitChanges();
+}
+
+//------------------------------------------------------------------------------
+bool UpdateCheckConfig::checkExtensionVersion( const rtl::OUString& rExtensionName,
+ const rtl::OUString& rVersion )
+{
+ const rtl::OUString aExtName = UNISTRING( EXTENSION_PREFIX ) + rExtensionName;
+
+ if( m_xContainer->hasByName( aExtName ) )
+ {
+ uno::Any aValue = m_xContainer->getByName( aExtName );
+ rtl::OUString aStoredVersion;
+ aValue >>= aStoredVersion;
+
+ if ( isVersionGreater( rVersion, aStoredVersion ) )
+ return true;
+ else
+ {
+ m_xContainer->removeByName( aExtName );
+ 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();
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */