LibreOffice Module desktop (master)  1
dp_informationprovider.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <cppuhelper/implbase.hxx>
22 
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/task/XAbortChannel.hpp>
31 #include <com/sun/star/ucb/ContentCreationException.hpp>
32 #include <com/sun/star/uno/XComponentContext.hpp>
33 #include <com/sun/star/ucb/XCommandEnvironment.hpp>
34 #include <com/sun/star/xml/dom/XElement.hpp>
35 
36 #include <com/sun/star/uno/Reference.hxx>
37 #include <osl/diagnose.h>
38 #include <rtl/ustring.hxx>
39 #include <tools/diagnose_ex.h>
40 #include <ucbhelper/content.hxx>
41 
42 #include <dp_dependencies.hxx>
44 #include <dp_identifier.hxx>
45 #include <dp_version.hxx>
46 #include <dp_update.hxx>
47 
48 namespace beans = com::sun::star::beans ;
50 namespace lang = com::sun::star::lang ;
51 namespace task = com::sun::star::task ;
52 namespace css_ucb = com::sun::star::ucb ;
53 namespace uno = com::sun::star::uno ;
54 namespace xml = com::sun::star::xml ;
55 
56 
57 namespace dp_info {
58 
59 namespace {
60 
61 class PackageInformationProvider :
62  public ::cppu::WeakImplHelper< deployment::XPackageInformationProvider, lang::XServiceInfo >
63 
64 {
65  public:
66  explicit PackageInformationProvider( uno::Reference< uno::XComponentContext >const& xContext);
67 
68  // XServiceInfo
69  virtual OUString SAL_CALL getImplementationName() override;
70  virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
71  virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
72 
73  // XPackageInformationProvider
74  virtual OUString SAL_CALL getPackageLocation( const OUString& extensionId ) override;
75  virtual uno::Sequence< uno::Sequence< OUString > > SAL_CALL isUpdateAvailable( const OUString& extensionId ) override;
76  virtual uno::Sequence< uno::Sequence< OUString > > SAL_CALL getExtensionList() override;
77 
78 private:
79 
80  uno::Reference< uno::XComponentContext> mxContext;
81 
82  OUString getPackageLocation( const OUString& repository,
83  const OUString& _sExtensionId );
84 
85  uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation;
86 };
87 
88 }
89 
90 PackageInformationProvider::PackageInformationProvider( uno::Reference< uno::XComponentContext > const& xContext) :
91  mxContext( xContext ),
92  mxUpdateInformation( deployment::UpdateInformationProvider::create( xContext ) )
93 {
94 }
95 
96 // XServiceInfo
97 OUString PackageInformationProvider::getImplementationName()
98 {
99  return "com.sun.star.comp.deployment.PackageInformationProvider";
100 }
101 
102 sal_Bool PackageInformationProvider::supportsService( const OUString& ServiceName )
103 {
104  return cppu::supportsService(this, ServiceName);
105 }
106 
107 css::uno::Sequence< OUString > PackageInformationProvider::getSupportedServiceNames()
108 {
109  // a private one:
110  return { "com.sun.star.comp.deployment.PackageInformationProvider" };
111 }
112 
113 OUString PackageInformationProvider::getPackageLocation(
114  const OUString & repository,
115  const OUString& _rExtensionId )
116 {
117  OUString aLocationURL;
118  uno::Reference<deployment::XExtensionManager> xManager =
119  deployment::ExtensionManager::get(mxContext);
120 
121  if ( xManager.is() )
122  {
123  const uno::Sequence< uno::Reference< deployment::XPackage > > packages(
124  xManager->getDeployedExtensions(
125  repository,
126  uno::Reference< task::XAbortChannel >(),
127  uno::Reference< css_ucb::XCommandEnvironment > () ) );
128 
129  for ( int pos = packages.getLength(); pos--; )
130  {
131  try
132  {
133  const beans::Optional< OUString > aID = packages[ pos ]->getIdentifier();
134  if ( aID.IsPresent && (aID.Value == _rExtensionId ) )
135  {
136  aLocationURL = packages[ pos ]->getURL();
137  break;
138  }
139  }
140  catch ( uno::RuntimeException & ) {}
141  }
142  }
143 
144  return aLocationURL;
145 }
146 
147 
148 OUString SAL_CALL
149 PackageInformationProvider::getPackageLocation( const OUString& _sExtensionId )
150 {
151  OUString aLocationURL = getPackageLocation( "user", _sExtensionId );
152 
153  if ( aLocationURL.isEmpty() )
154  {
155  aLocationURL = getPackageLocation( "shared", _sExtensionId );
156  }
157  if ( aLocationURL.isEmpty() )
158  {
159  aLocationURL = getPackageLocation( "bundled", _sExtensionId );
160  }
161  if ( !aLocationURL.isEmpty() )
162  {
163  try
164  {
165  ::ucbhelper::Content aContent( aLocationURL, nullptr, mxContext );
166  aLocationURL = aContent.getURL();
167  }
168  catch (const css::ucb::ContentCreationException&)
169  {
170  TOOLS_WARN_EXCEPTION("desktop.deployment", "ignoring");
171  }
172  }
173  return aLocationURL;
174 }
175 
176 uno::Sequence< uno::Sequence< OUString > > SAL_CALL
177 PackageInformationProvider::isUpdateAvailable( const OUString& _sExtensionId )
178 {
179  uno::Sequence< uno::Sequence< OUString > > aList;
180 
181  uno::Reference<deployment::XExtensionManager> extMgr =
182  deployment::ExtensionManager::get(mxContext);
183 
184  if (!extMgr.is())
185  {
186  OSL_ASSERT(false);
187  return aList;
188  }
189  std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
190  dp_misc::UpdateInfoMap updateInfoMap;
191  if (!_sExtensionId.isEmpty())
192  {
193  std::vector<uno::Reference<deployment::XPackage> > vecExtensions;
194  uno::Reference<deployment::XPackage> extension;
195  try
196  {
198  extMgr->getExtensionsWithSameIdentifier(
199  _sExtensionId, _sExtensionId, uno::Reference<css_ucb::XCommandEnvironment>()));
200  vecExtensions.push_back(extension);
201  }
202  catch (lang::IllegalArgumentException &)
203  {
204  OSL_ASSERT(false);
205  }
206  updateInfoMap = dp_misc::getOnlineUpdateInfos(
207  mxContext, extMgr, mxUpdateInformation, &vecExtensions, errors);
208  }
209  else
210  {
211  updateInfoMap = dp_misc::getOnlineUpdateInfos(
212  mxContext, extMgr, mxUpdateInformation, nullptr, errors);
213  }
214 
215  int nCount = 0;
216  for (auto const& updateInfo : updateInfoMap)
217  {
218  dp_misc::UpdateInfo const & info = updateInfo.second;
219 
220  OUString sOnlineVersion;
221  if (info.info.is())
222  {
223  // check, if there are unsatisfied dependencies and ignore this online update
225  uno::Sequence< uno::Reference< xml::dom::XElement > >
226  ds( dp_misc::Dependencies::check( infoset ) );
227  if ( ! ds.hasElements() )
228  sOnlineVersion = info.version;
229  }
230 
231  OUString sVersionUser;
232  OUString sVersionShared;
233  OUString sVersionBundled;
234  uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
235  try {
236  extensions = extMgr->getExtensionsWithSameIdentifier(
237  dp_misc::getIdentifier(info.extension), info.extension->getName(),
238  uno::Reference<css_ucb::XCommandEnvironment>());
239  } catch (const lang::IllegalArgumentException&) {
240  TOOLS_WARN_EXCEPTION("desktop.deployment", "ignoring");
241  continue;
242  }
243  OSL_ASSERT(extensions.getLength() == 3);
244  if (extensions[0].is() )
245  sVersionUser = extensions[0]->getVersion();
246  if (extensions[1].is() )
247  sVersionShared = extensions[1]->getVersion();
248  if (extensions[2].is() )
249  sVersionBundled = extensions[2]->getVersion();
250 
251  bool bSharedReadOnly = extMgr->isReadOnlyRepository("shared");
252 
254  bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
256  bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
257 
258  OUString updateVersionUser;
259  OUString updateVersionShared;
260  if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
261  updateVersionUser = dp_misc::getHighestVersion(
262  sVersionShared, sVersionBundled, sOnlineVersion);
263  if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
264  updateVersionShared = dp_misc::getHighestVersion(
265  OUString(), sVersionBundled, sOnlineVersion);
266  OUString updateVersion;
267  if (dp_misc::compareVersions(updateVersionUser, updateVersionShared) == dp_misc::GREATER)
268  updateVersion = updateVersionUser;
269  else
270  updateVersion = updateVersionShared;
271  if (!updateVersion.isEmpty())
272  {
273 
274  OUString aNewEntry[2];
275  aNewEntry[0] = updateInfo.first;
276  aNewEntry[1] = updateVersion;
277  aList.realloc( ++nCount );
278  aList[ nCount-1 ] = ::uno::Sequence< OUString >( aNewEntry, 2 );
279  }
280  }
281  return aList;
282 }
283 
284 
285 uno::Sequence< uno::Sequence< OUString > > SAL_CALL PackageInformationProvider::getExtensionList()
286 {
287  const uno::Reference<deployment::XExtensionManager> mgr =
288  deployment::ExtensionManager::get(mxContext);
289 
290  if (!mgr.is())
291  return uno::Sequence< uno::Sequence< OUString > >();
292 
293  const uno::Sequence< uno::Sequence< uno::Reference<deployment::XPackage > > >
294  allExt = mgr->getAllExtensions(
295  uno::Reference< task::XAbortChannel >(),
296  uno::Reference< css_ucb::XCommandEnvironment > () );
297 
298  uno::Sequence< uno::Sequence< OUString > > retList;
299 
300  sal_Int32 cAllIds = allExt.getLength();
301  retList.realloc(cAllIds);
302 
303  for (sal_Int32 i = 0; i < cAllIds; i++)
304  {
305  //The inner sequence contains extensions with the same identifier from
306  //all the different repositories, that is user, share, bundled.
307  const uno::Sequence< uno::Reference< deployment::XPackage > > &
308  seqExtension = allExt[i];
309  sal_Int32 cExt = seqExtension.getLength();
310  OSL_ASSERT(cExt == 3);
311  for (sal_Int32 j = 0; j < cExt; j++)
312  {
313  //ToDo according to the old code the first found extension is used
314  //even if another one with the same id has a better version.
315  uno::Reference< deployment::XPackage > const & xExtension( seqExtension[j] );
316  if (xExtension.is())
317  {
318  OUString aNewEntry[2];
319  aNewEntry[0] = dp_misc::getIdentifier(xExtension);
320  aNewEntry[1] = xExtension->getVersion();
321  retList[i] = ::uno::Sequence< OUString >( aNewEntry, 2 );
322  break;
323  }
324  }
325  }
326  return retList;
327 }
328 
329 
330 } // namespace dp_info
331 
332 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
334  css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
335 {
336  return cppu::acquire(new dp_info::PackageInformationProvider(context));
337 }
338 
339 
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::map< OUString, UpdateInfo > UpdateInfoMap
Definition: dp_update.hxx:100
exports com.sun.star. packages
uno::Reference< uno::XComponentContext > mxContext
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC Order compareVersions(OUString const &version1, OUString const &version2)
Definition: dp_version.cxx:41
css::uno::Reference< css::deployment::XPackageRegistry > create(css::uno::Reference< css::deployment::XPackageRegistry > const &xRootRegistry, OUString const &context, OUString const &cachePath, css::uno::Reference< css::uno::XComponentContext > const &xComponentContext)
size_t pos
int nCount
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation
#define TOOLS_WARN_EXCEPTION(area, stream)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC UPDATE_SOURCE isUpdateSharedExtension(bool bReadOnlyShared, OUString const &sharedVersion, OUString const &bundledVersion, OUString const &onlineVersion)
Definition: dp_update.cxx:284
int i
unsigned char sal_Bool
css::uno::Reference< css::xml::dom::XNode > info
Definition: dp_update.hxx:97
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC UPDATE_SOURCE isUpdateUserExtension(bool bReadOnlyShared, OUString const &userVersion, OUString const &sharedVersion, OUString const &bundledVersion, OUString const &onlineVersion)
Definition: dp_update.cxx:234
static uno::Reference< css::uno::XComponentContext > xContext
Definition: init.cxx:2180
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC UpdateInfoMap getOnlineUpdateInfos(css::uno::Reference< css::uno::XComponentContext > const &xContext, css::uno::Reference< css::deployment::XExtensionManager > const &xExtMgr, css::uno::Reference< css::deployment::XUpdateInformationProvider > const &updateInformation, std::vector< css::uno::Reference< css::deployment::XPackage > > const *extensionList, std::vector< std::pair< css::uno::Reference< css::deployment::XPackage >, css::uno::Any > > &out_errors)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC css::uno::Sequence< css::uno::Reference< css::xml::dom::XElement > > check(dp_misc::DescriptionInfoset const &infoset)
Check for unsatisfied dependencies.
css::uno::Reference< css::deployment::XPackage > extension
Definition: dp_update.hxx:94
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_deployment_PackageInformationProvider_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString getHighestVersion(OUString const &sharedVersion, OUString const &bundledVersion, OUString const &onlineVersion)
Definition: dp_update.cxx:390
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC OUString getIdentifier(css::uno::Reference< css::deployment::XPackage > const &package)
Gets the identifier of a package.
Access to the content of an XML description element.
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC css::uno::Reference< css::deployment::XPackage > getExtensionWithHighestVersion(css::uno::Sequence< css::uno::Reference< css::deployment::XPackage > > const &seqExtensionsWithSameId)