Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / desktop / source / deployment / manager / dp_informationprovider.cxx
blob5eafb605c91a736de9dc552e5186e4977ea5d09d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <cppuhelper/implbase.hxx>
21 #include <comphelper/servicedecl.hxx>
23 #include <com/sun/star/deployment/UpdateInformationProvider.hpp>
24 #include <com/sun/star/deployment/XPackage.hpp>
25 #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
26 #include <com/sun/star/deployment/ExtensionManager.hpp>
27 #include <com/sun/star/deployment/XUpdateInformationProvider.hpp>
28 #include <com/sun/star/lang/IllegalArgumentException.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/registry/XRegistryKey.hpp>
31 #include <com/sun/star/task/XAbortChannel.hpp>
32 #include <com/sun/star/ucb/ContentCreationException.hpp>
33 #include <com/sun/star/uno/XComponentContext.hpp>
34 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
35 #include <com/sun/star/xml/dom/XElement.hpp>
36 #include <com/sun/star/xml/dom/XNode.hpp>
38 #include <com/sun/star/uno/Reference.hxx>
39 #include <osl/diagnose.h>
40 #include <sal/log.hxx>
41 #include <rtl/ustring.hxx>
42 #include <tools/diagnose_ex.h>
43 #include <ucbhelper/content.hxx>
45 #include <dp_dependencies.hxx>
46 #include <dp_descriptioninfoset.hxx>
47 #include <dp_identifier.hxx>
48 #include <dp_services.hxx>
49 #include <dp_version.hxx>
50 #include <dp_misc.h>
51 #include <dp_update.hxx>
53 namespace beans = com::sun::star::beans ;
54 namespace deployment = com::sun::star::deployment ;
55 namespace lang = com::sun::star::lang ;
56 namespace task = com::sun::star::task ;
57 namespace css_ucb = com::sun::star::ucb ;
58 namespace uno = com::sun::star::uno ;
59 namespace xml = com::sun::star::xml ;
62 namespace dp_info {
64 class PackageInformationProvider :
65 public ::cppu::WeakImplHelper< deployment::XPackageInformationProvider >
68 public:
69 explicit PackageInformationProvider( uno::Reference< uno::XComponentContext >const& xContext);
71 // XPackageInformationProvider
72 virtual OUString SAL_CALL getPackageLocation( const OUString& extensionId ) override;
73 virtual uno::Sequence< uno::Sequence< OUString > > SAL_CALL isUpdateAvailable( const OUString& extensionId ) override;
74 virtual uno::Sequence< uno::Sequence< OUString > > SAL_CALL getExtensionList() override;
76 private:
78 uno::Reference< uno::XComponentContext> mxContext;
80 OUString getPackageLocation( const OUString& repository,
81 const OUString& _sExtensionId );
83 uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation;
87 PackageInformationProvider::PackageInformationProvider( uno::Reference< uno::XComponentContext > const& xContext) :
88 mxContext( xContext ),
89 mxUpdateInformation( deployment::UpdateInformationProvider::create( xContext ) )
93 OUString PackageInformationProvider::getPackageLocation(
94 const OUString & repository,
95 const OUString& _rExtensionId )
97 OUString aLocationURL;
98 uno::Reference<deployment::XExtensionManager> xManager =
99 deployment::ExtensionManager::get(mxContext);
101 if ( xManager.is() )
103 const uno::Sequence< uno::Reference< deployment::XPackage > > packages(
104 xManager->getDeployedExtensions(
105 repository,
106 uno::Reference< task::XAbortChannel >(),
107 uno::Reference< css_ucb::XCommandEnvironment > () ) );
109 for ( int pos = packages.getLength(); pos--; )
113 const beans::Optional< OUString > aID = packages[ pos ]->getIdentifier();
114 if ( aID.IsPresent && (aID.Value == _rExtensionId ) )
116 aLocationURL = packages[ pos ]->getURL();
117 break;
120 catch ( uno::RuntimeException & ) {}
124 return aLocationURL;
128 OUString SAL_CALL
129 PackageInformationProvider::getPackageLocation( const OUString& _sExtensionId )
131 OUString aLocationURL = getPackageLocation( "user", _sExtensionId );
133 if ( aLocationURL.isEmpty() )
135 aLocationURL = getPackageLocation( "shared", _sExtensionId );
137 if ( aLocationURL.isEmpty() )
139 aLocationURL = getPackageLocation( "bundled", _sExtensionId );
141 if ( !aLocationURL.isEmpty() )
145 ::ucbhelper::Content aContent( aLocationURL, nullptr, mxContext );
146 aLocationURL = aContent.getURL();
148 catch (const css::ucb::ContentCreationException&)
150 TOOLS_WARN_EXCEPTION("desktop.deployment", "ignoring");
153 return aLocationURL;
156 uno::Sequence< uno::Sequence< OUString > > SAL_CALL
157 PackageInformationProvider::isUpdateAvailable( const OUString& _sExtensionId )
159 uno::Sequence< uno::Sequence< OUString > > aList;
161 uno::Reference<deployment::XExtensionManager> extMgr =
162 deployment::ExtensionManager::get(mxContext);
164 if (!extMgr.is())
166 OSL_ASSERT(false);
167 return aList;
169 std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
170 dp_misc::UpdateInfoMap updateInfoMap;
171 if (!_sExtensionId.isEmpty())
173 std::vector<uno::Reference<deployment::XPackage> > vecExtensions;
174 uno::Reference<deployment::XPackage> extension;
177 extension = dp_misc::getExtensionWithHighestVersion(
178 extMgr->getExtensionsWithSameIdentifier(
179 _sExtensionId, _sExtensionId, uno::Reference<css_ucb::XCommandEnvironment>()));
180 vecExtensions.push_back(extension);
182 catch (lang::IllegalArgumentException &)
184 OSL_ASSERT(false);
186 updateInfoMap = dp_misc::getOnlineUpdateInfos(
187 mxContext, extMgr, mxUpdateInformation, &vecExtensions, errors);
189 else
191 updateInfoMap = dp_misc::getOnlineUpdateInfos(
192 mxContext, extMgr, mxUpdateInformation, nullptr, errors);
195 int nCount = 0;
196 for (auto const& updateInfo : updateInfoMap)
198 dp_misc::UpdateInfo const & info = updateInfo.second;
200 OUString sOnlineVersion;
201 if (info.info.is())
203 // check, if there are unsatisfied dependencies and ignore this online update
204 dp_misc::DescriptionInfoset infoset(mxContext, info.info);
205 uno::Sequence< uno::Reference< xml::dom::XElement > >
206 ds( dp_misc::Dependencies::check( infoset ) );
207 if ( ! ds.hasElements() )
208 sOnlineVersion = info.version;
211 OUString sVersionUser;
212 OUString sVersionShared;
213 OUString sVersionBundled;
214 uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
215 try {
216 extensions = extMgr->getExtensionsWithSameIdentifier(
217 dp_misc::getIdentifier(info.extension), info.extension->getName(),
218 uno::Reference<css_ucb::XCommandEnvironment>());
219 } catch (const lang::IllegalArgumentException&) {
220 TOOLS_WARN_EXCEPTION("desktop.deployment", "ignoring");
221 continue;
223 OSL_ASSERT(extensions.getLength() == 3);
224 if (extensions[0].is() )
225 sVersionUser = extensions[0]->getVersion();
226 if (extensions[1].is() )
227 sVersionShared = extensions[1]->getVersion();
228 if (extensions[2].is() )
229 sVersionBundled = extensions[2]->getVersion();
231 bool bSharedReadOnly = extMgr->isReadOnlyRepository("shared");
233 dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
234 bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
235 dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
236 bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
238 OUString updateVersionUser;
239 OUString updateVersionShared;
240 if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
241 updateVersionUser = dp_misc::getHighestVersion(
242 sVersionShared, sVersionBundled, sOnlineVersion);
243 if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
244 updateVersionShared = dp_misc::getHighestVersion(
245 OUString(), sVersionBundled, sOnlineVersion);
246 OUString updateVersion;
247 if (dp_misc::compareVersions(updateVersionUser, updateVersionShared) == dp_misc::GREATER)
248 updateVersion = updateVersionUser;
249 else
250 updateVersion = updateVersionShared;
251 if (!updateVersion.isEmpty())
254 OUString aNewEntry[2];
255 aNewEntry[0] = updateInfo.first;
256 aNewEntry[1] = updateVersion;
257 aList.realloc( ++nCount );
258 aList[ nCount-1 ] = ::uno::Sequence< OUString >( aNewEntry, 2 );
261 return aList;
265 uno::Sequence< uno::Sequence< OUString > > SAL_CALL PackageInformationProvider::getExtensionList()
267 const uno::Reference<deployment::XExtensionManager> mgr =
268 deployment::ExtensionManager::get(mxContext);
270 if (!mgr.is())
271 return uno::Sequence< uno::Sequence< OUString > >();
273 const uno::Sequence< uno::Sequence< uno::Reference<deployment::XPackage > > >
274 allExt = mgr->getAllExtensions(
275 uno::Reference< task::XAbortChannel >(),
276 uno::Reference< css_ucb::XCommandEnvironment > () );
278 uno::Sequence< uno::Sequence< OUString > > retList;
280 sal_Int32 cAllIds = allExt.getLength();
281 retList.realloc(cAllIds);
283 for (sal_Int32 i = 0; i < cAllIds; i++)
285 //The inner sequence contains extensions with the same identifier from
286 //all the different repositories, that is user, share, bundled.
287 const uno::Sequence< uno::Reference< deployment::XPackage > > &
288 seqExtension = allExt[i];
289 sal_Int32 cExt = seqExtension.getLength();
290 OSL_ASSERT(cExt == 3);
291 for (sal_Int32 j = 0; j < cExt; j++)
293 //ToDo according to the old code the first found extension is used
294 //even if another one with the same id has a better version.
295 uno::Reference< deployment::XPackage > const & xExtension( seqExtension[j] );
296 if (xExtension.is())
298 OUString aNewEntry[2];
299 aNewEntry[0] = dp_misc::getIdentifier(xExtension);
300 aNewEntry[1] = xExtension->getVersion();
301 retList[i] = ::uno::Sequence< OUString >( aNewEntry, 2 );
302 break;
306 return retList;
310 namespace sdecl = comphelper::service_decl;
311 sdecl::class_<PackageInformationProvider> const servicePIP;
312 sdecl::ServiceDecl const serviceDecl(
313 servicePIP,
314 // a private one:
315 "com.sun.star.comp.deployment.PackageInformationProvider",
316 "com.sun.star.comp.deployment.PackageInformationProvider" );
318 } // namespace dp_info
321 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */