diff options
Diffstat (limited to 'desktop/source/deployment/manager/dp_informationprovider.cxx')
-rw-r--r-- | desktop/source/deployment/manager/dp_informationprovider.cxx | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/desktop/source/deployment/manager/dp_informationprovider.cxx b/desktop/source/deployment/manager/dp_informationprovider.cxx new file mode 100644 index 000000000000..4cc43a8386d8 --- /dev/null +++ b/desktop/source/deployment/manager/dp_informationprovider.cxx @@ -0,0 +1,393 @@ +/************************************************************************* + * + * 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_desktop.hxx" + +#include <cppuhelper/implbase3.hxx> + +#include "comphelper/servicedecl.hxx" + +#include "com/sun/star/deployment/UpdateInformationProvider.hpp" +#include "com/sun/star/deployment/XPackage.hpp" +#include "com/sun/star/deployment/XPackageInformationProvider.hpp" +#include "com/sun/star/deployment/ExtensionManager.hpp" +#include "com/sun/star/deployment/XUpdateInformationProvider.hpp" +#include "com/sun/star/lang/XServiceInfo.hpp" +#include "com/sun/star/registry/XRegistryKey.hpp" +#include "com/sun/star/task/XAbortChannel.hpp" +#include "com/sun/star/ucb/CommandFailedException.hpp" +#include "com/sun/star/ucb/XCommandEnvironment.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" +#include "com/sun/star/xml/dom/XElement.hpp" +#include "com/sun/star/xml/dom/XNode.hpp" + +#include "com/sun/star/uno/Reference.hxx" +#include "rtl/ustring.hxx" +#include "ucbhelper/content.hxx" + +#include "dp_dependencies.hxx" +#include "dp_descriptioninfoset.hxx" +#include "dp_identifier.hxx" +#include "dp_version.hxx" +#include "dp_misc.h" +#include "dp_update.hxx" + +namespace beans = com::sun::star::beans ; +namespace deployment = com::sun::star::deployment ; +namespace lang = com::sun::star::lang ; +namespace registry = com::sun::star::registry ; +namespace task = com::sun::star::task ; +namespace css_ucb = com::sun::star::ucb ; +namespace uno = com::sun::star::uno ; +namespace xml = com::sun::star::xml ; + +#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) + +namespace dp_info { + +class PackageInformationProvider : + public ::cppu::WeakImplHelper3< deployment::XPackageInformationProvider, + css_ucb::XCommandEnvironment, + task::XInteractionHandler > +{ + public: + PackageInformationProvider( uno::Reference< uno::XComponentContext >const& xContext); + virtual ~PackageInformationProvider(); + + static uno::Sequence< rtl::OUString > getServiceNames(); + static rtl::OUString getImplName(); + + // XInteractionHandler + virtual void SAL_CALL handle( const uno::Reference< task::XInteractionRequest >& Request ) + throw( uno::RuntimeException ); + // XCommandEnvironment + virtual uno::Reference< task::XInteractionHandler > SAL_CALL getInteractionHandler() + throw ( uno::RuntimeException ) { return static_cast<task::XInteractionHandler*>(this); }; + + virtual uno::Reference< css_ucb::XProgressHandler > SAL_CALL getProgressHandler() + throw ( uno::RuntimeException ) { return uno::Reference< css_ucb::XProgressHandler >(); }; + + // XPackageInformationProvider + virtual rtl::OUString SAL_CALL getPackageLocation( const rtl::OUString& extensionId ) + throw ( uno::RuntimeException ); + virtual uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL isUpdateAvailable( const rtl::OUString& extensionId ) + throw ( uno::RuntimeException ); + virtual uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL getExtensionList() + throw ( uno::RuntimeException ); +//--------- +private: + + uno::Reference< uno::XComponentContext> mxContext; + + rtl::OUString getPackageLocation( const rtl::OUString& repository, + const rtl::OUString& _sExtensionId ); + + uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation; +}; + +//------------------------------------------------------------------------------ + +PackageInformationProvider::PackageInformationProvider( uno::Reference< uno::XComponentContext > const& xContext) : + mxContext( xContext ), + mxUpdateInformation( deployment::UpdateInformationProvider::create( xContext ) ) +{ +} + +//------------------------------------------------------------------------------ + +PackageInformationProvider::~PackageInformationProvider() +{ +} + +//------------------------------------------------------------------------------ +void SAL_CALL PackageInformationProvider::handle( uno::Reference< task::XInteractionRequest > const & rRequest) + throw (uno::RuntimeException) +{ + uno::Sequence< uno::Reference< task::XInteractionContinuation > > xContinuations = rRequest->getContinuations(); + if ( xContinuations.getLength() == 1 ) + { + xContinuations[0]->select(); + } +} + +//------------------------------------------------------------------------------ +rtl::OUString PackageInformationProvider::getPackageLocation( + const rtl::OUString & repository, + const rtl::OUString& _rExtensionId ) +{ + rtl::OUString aLocationURL; + uno::Reference<deployment::XExtensionManager> xManager = + deployment::ExtensionManager::get(mxContext); + + if ( xManager.is() ) + { + const uno::Sequence< uno::Reference< deployment::XPackage > > packages( + xManager->getDeployedExtensions( + repository, + uno::Reference< task::XAbortChannel >(), + static_cast < XCommandEnvironment *> (this) ) ); + + for ( int pos = packages.getLength(); pos--; ) + { + try + { + const rtl::OUString aName = packages[ pos ]->getName(); + const beans::Optional< rtl::OUString > aID = packages[ pos ]->getIdentifier(); + if ( aID.IsPresent && aID.Value.compareTo( _rExtensionId ) == 0 ) + { + aLocationURL = packages[ pos ]->getURL(); + break; + } + } + catch ( uno::RuntimeException & ) {} + } + } + + return aLocationURL; +} + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +rtl::OUString SAL_CALL +PackageInformationProvider::getPackageLocation( const rtl::OUString& _sExtensionId ) + throw ( uno::RuntimeException ) +{ + rtl::OUString aLocationURL = getPackageLocation( UNISTRING("user"), _sExtensionId ); + + if ( aLocationURL.getLength() == 0 ) + { + aLocationURL = getPackageLocation( UNISTRING("shared"), _sExtensionId ); + } + if ( aLocationURL.getLength() == 0 ) + { + aLocationURL = getPackageLocation( UNISTRING("bundled"), _sExtensionId ); + } + if ( aLocationURL.getLength() ) + { + ::ucbhelper::Content aContent( aLocationURL, NULL ); + aLocationURL = aContent.getURL(); + } + return aLocationURL; +} + +//------------------------------------------------------------------------------ + +uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL +PackageInformationProvider::isUpdateAvailable( const rtl::OUString& _sExtensionId ) + throw ( uno::RuntimeException ) +{ + uno::Sequence< uno::Sequence< rtl::OUString > > aList; + + uno::Reference<deployment::XExtensionManager> extMgr = + deployment::ExtensionManager::get(mxContext); + + if (!extMgr.is()) + { + OSL_ASSERT(0); + return aList; + } + std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors; + dp_misc::UpdateInfoMap updateInfoMap; + if (_sExtensionId.getLength()) + { + std::vector<uno::Reference<deployment::XPackage> > vecExtensions; + uno::Reference<deployment::XPackage> extension; + try + { + extension = dp_misc::getExtensionWithHighestVersion( + extMgr->getExtensionsWithSameIdentifier( + _sExtensionId, _sExtensionId, uno::Reference<css_ucb::XCommandEnvironment>())); + vecExtensions.push_back(extension); + } + catch (lang::IllegalArgumentException &) + { + OSL_ASSERT(0); + } + updateInfoMap = dp_misc::getOnlineUpdateInfos( + mxContext, extMgr, mxUpdateInformation, &vecExtensions, errors); + } + else + { + updateInfoMap = dp_misc::getOnlineUpdateInfos( + mxContext, extMgr, mxUpdateInformation, NULL, errors); + } + + int nCount = 0; + for (dp_misc::UpdateInfoMap::iterator i(updateInfoMap.begin()); i != updateInfoMap.end(); i++) + { + dp_misc::UpdateInfo const & info = i->second; + + rtl::OUString sOnlineVersion; + if (info.info.is()) + { + // check, if there are unsatisfied dependencies and ignore this online update + dp_misc::DescriptionInfoset infoset(mxContext, info.info); + uno::Sequence< uno::Reference< xml::dom::XElement > > + ds( dp_misc::Dependencies::check( infoset ) ); + if ( ! ds.getLength() ) + sOnlineVersion = info.version; + } + + rtl::OUString sVersionUser; + rtl::OUString sVersionShared; + rtl::OUString sVersionBundled; + uno::Sequence< uno::Reference< deployment::XPackage> > extensions; + try { + extensions = extMgr->getExtensionsWithSameIdentifier( + dp_misc::getIdentifier(info.extension), info.extension->getName(), + uno::Reference<css_ucb::XCommandEnvironment>()); + } catch (lang::IllegalArgumentException& ) { + OSL_ASSERT(0); + } + OSL_ASSERT(extensions.getLength() == 3); + if (extensions[0].is() ) + sVersionUser = extensions[0]->getVersion(); + if (extensions[1].is() ) + sVersionShared = extensions[1]->getVersion(); + if (extensions[2].is() ) + sVersionBundled = extensions[2]->getVersion(); + + bool bSharedReadOnly = extMgr->isReadOnlyRepository(OUSTR("shared")); + + dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension( + bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion); + dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension( + bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion); + + rtl::OUString updateVersionUser; + rtl::OUString updateVersionShared; + if (sourceUser != dp_misc::UPDATE_SOURCE_NONE) + updateVersionUser = dp_misc::getHighestVersion( + rtl::OUString(), sVersionShared, sVersionBundled, sOnlineVersion); + if (sourceShared != dp_misc::UPDATE_SOURCE_NONE) + updateVersionShared = dp_misc::getHighestVersion( + rtl::OUString(), rtl::OUString(), sVersionBundled, sOnlineVersion); + rtl::OUString updateVersion; + if (dp_misc::compareVersions(updateVersionUser, updateVersionShared) == dp_misc::GREATER) + updateVersion = updateVersionUser; + else + updateVersion = updateVersionShared; + if (updateVersion.getLength()) + { + + rtl::OUString aNewEntry[2]; + aNewEntry[0] = i->first; + aNewEntry[1] = updateVersion; + aList.realloc( ++nCount ); + aList[ nCount-1 ] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 ); + } + } + return aList; +} + +//------------------------------------------------------------------------------ +uno::Sequence< uno::Sequence< rtl::OUString > > SAL_CALL PackageInformationProvider::getExtensionList() + throw ( uno::RuntimeException ) +{ + const uno::Reference<deployment::XExtensionManager> mgr = + deployment::ExtensionManager::get(mxContext); + + if (!mgr.is()) + return uno::Sequence< uno::Sequence< rtl::OUString > >(); + + const uno::Sequence< uno::Sequence< uno::Reference<deployment::XPackage > > > + allExt = mgr->getAllExtensions( + uno::Reference< task::XAbortChannel >(), + static_cast < XCommandEnvironment *> (this) ); + + uno::Sequence< uno::Sequence< rtl::OUString > > retList; + + sal_Int32 cAllIds = allExt.getLength(); + retList.realloc(cAllIds); + + for (sal_Int32 i = 0; i < cAllIds; i++) + { + //The inner sequence contains extensions with the same identifier from + //all the different repositories, that is user, share, bundled. + const uno::Sequence< uno::Reference< deployment::XPackage > > & + seqExtension = allExt[i]; + sal_Int32 cExt = seqExtension.getLength(); + OSL_ASSERT(cExt == 3); + for (sal_Int32 j = 0; j < cExt; j++) + { + //ToDo according to the old code the first found extenions is used + //even if another one with the same id has a better version. + uno::Reference< deployment::XPackage > const & xExtension( seqExtension[j] ); + if (xExtension.is()) + { + rtl::OUString aNewEntry[2]; + aNewEntry[0] = dp_misc::getIdentifier(xExtension); + aNewEntry[1] = xExtension->getVersion(); + retList[i] = ::uno::Sequence< rtl::OUString >( aNewEntry, 2 ); + break; + } + } + } + return retList; +} + + +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ + +namespace sdecl = comphelper::service_decl; +sdecl::class_<PackageInformationProvider> servicePIP; +extern sdecl::ServiceDecl const serviceDecl( + servicePIP, + // a private one: + "com.sun.star.comp.deployment.PackageInformationProvider", + "com.sun.star.comp.deployment.PackageInformationProvider" ); + +//------------------------------------------------------------------------------ +bool singleton_entries( + uno::Reference< registry::XRegistryKey > const & xRegistryKey ) +{ + try { + uno::Reference< registry::XRegistryKey > xKey( + xRegistryKey->createKey( + serviceDecl.getImplementationName() + + // xxx todo: use future generated function to get singleton name + UNISTRING("/UNO/SINGLETONS/" + "com.sun.star.deployment.PackageInformationProvider") ) ); + xKey->setStringValue( serviceDecl.getSupportedServiceNames()[0] ); + return true; + } + catch (registry::InvalidRegistryException & exc) { + (void) exc; // avoid warnings + OSL_ENSURE( 0, ::rtl::OUStringToOString( + exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); + return false; + } +} + +} // namespace dp_info + + |