Line data Source code
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/implbase3.hxx>
21 : #include <comphelper/servicedecl.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/XServiceInfo.hpp>
29 : #include <com/sun/star/registry/XRegistryKey.hpp>
30 : #include <com/sun/star/task/XAbortChannel.hpp>
31 : #include <com/sun/star/uno/XComponentContext.hpp>
32 : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
33 : #include <com/sun/star/xml/dom/XElement.hpp>
34 : #include <com/sun/star/xml/dom/XNode.hpp>
35 :
36 : #include <com/sun/star/uno/Reference.hxx>
37 : #include <rtl/ustring.hxx>
38 : #include <ucbhelper/content.hxx>
39 :
40 : #include "dp_dependencies.hxx"
41 : #include "dp_descriptioninfoset.hxx"
42 : #include "dp_identifier.hxx"
43 : #include "dp_version.hxx"
44 : #include "dp_misc.h"
45 : #include "dp_update.hxx"
46 :
47 : namespace beans = com::sun::star::beans ;
48 : namespace deployment = com::sun::star::deployment ;
49 : namespace lang = com::sun::star::lang ;
50 : namespace registry = com::sun::star::registry ;
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 : class PackageInformationProvider :
60 : public ::cppu::WeakImplHelper1< deployment::XPackageInformationProvider >
61 :
62 : {
63 : public:
64 : PackageInformationProvider( uno::Reference< uno::XComponentContext >const& xContext);
65 : virtual ~PackageInformationProvider();
66 :
67 : // XPackageInformationProvider
68 : virtual OUString SAL_CALL getPackageLocation( const OUString& extensionId )
69 : throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
70 : virtual uno::Sequence< uno::Sequence< OUString > > SAL_CALL isUpdateAvailable( const OUString& extensionId )
71 : throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
72 : virtual uno::Sequence< uno::Sequence< OUString > > SAL_CALL getExtensionList()
73 : throw ( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
74 :
75 : private:
76 :
77 : uno::Reference< uno::XComponentContext> mxContext;
78 :
79 : OUString getPackageLocation( const OUString& repository,
80 : const OUString& _sExtensionId );
81 :
82 : uno::Reference< deployment::XUpdateInformationProvider > mxUpdateInformation;
83 : };
84 :
85 :
86 :
87 0 : PackageInformationProvider::PackageInformationProvider( uno::Reference< uno::XComponentContext > const& xContext) :
88 : mxContext( xContext ),
89 0 : mxUpdateInformation( deployment::UpdateInformationProvider::create( xContext ) )
90 : {
91 0 : }
92 :
93 :
94 :
95 0 : PackageInformationProvider::~PackageInformationProvider()
96 : {
97 0 : }
98 :
99 :
100 0 : OUString PackageInformationProvider::getPackageLocation(
101 : const OUString & repository,
102 : const OUString& _rExtensionId )
103 : {
104 0 : OUString aLocationURL;
105 : uno::Reference<deployment::XExtensionManager> xManager =
106 0 : deployment::ExtensionManager::get(mxContext);
107 :
108 0 : if ( xManager.is() )
109 : {
110 : const uno::Sequence< uno::Reference< deployment::XPackage > > packages(
111 0 : xManager->getDeployedExtensions(
112 : repository,
113 : uno::Reference< task::XAbortChannel >(),
114 0 : uno::Reference< css_ucb::XCommandEnvironment > () ) );
115 :
116 0 : for ( int pos = packages.getLength(); pos--; )
117 : {
118 : try
119 : {
120 0 : const beans::Optional< OUString > aID = packages[ pos ]->getIdentifier();
121 0 : if ( aID.IsPresent && (aID.Value == _rExtensionId ) )
122 : {
123 0 : aLocationURL = packages[ pos ]->getURL();
124 0 : break;
125 0 : }
126 : }
127 0 : catch ( uno::RuntimeException & ) {}
128 0 : }
129 : }
130 :
131 0 : return aLocationURL;
132 : }
133 :
134 :
135 :
136 : OUString SAL_CALL
137 0 : PackageInformationProvider::getPackageLocation( const OUString& _sExtensionId )
138 : throw ( uno::RuntimeException, std::exception )
139 : {
140 0 : OUString aLocationURL = getPackageLocation( OUString("user"), _sExtensionId );
141 :
142 0 : if ( aLocationURL.isEmpty() )
143 : {
144 0 : aLocationURL = getPackageLocation( OUString("shared"), _sExtensionId );
145 : }
146 0 : if ( aLocationURL.isEmpty() )
147 : {
148 0 : aLocationURL = getPackageLocation( OUString("bundled"), _sExtensionId );
149 : }
150 0 : if ( !aLocationURL.isEmpty() )
151 : {
152 : try
153 : {
154 0 : ::ucbhelper::Content aContent( aLocationURL, NULL, mxContext );
155 0 : aLocationURL = aContent.getURL();
156 : }
157 0 : catch (const css::ucb::ContentCreationException& e)
158 : {
159 : SAL_WARN(
160 : "desktop.deployment",
161 : "ignoring ContentCreationException \"" << e.Message << "\"");
162 : }
163 : }
164 0 : return aLocationURL;
165 : }
166 :
167 : uno::Sequence< uno::Sequence< OUString > > SAL_CALL
168 0 : PackageInformationProvider::isUpdateAvailable( const OUString& _sExtensionId )
169 : throw ( uno::RuntimeException, std::exception )
170 : {
171 0 : uno::Sequence< uno::Sequence< OUString > > aList;
172 :
173 : uno::Reference<deployment::XExtensionManager> extMgr =
174 0 : deployment::ExtensionManager::get(mxContext);
175 :
176 0 : if (!extMgr.is())
177 : {
178 : OSL_ASSERT(false);
179 0 : return aList;
180 : }
181 0 : std::vector<std::pair<uno::Reference<deployment::XPackage>, uno::Any > > errors;
182 0 : dp_misc::UpdateInfoMap updateInfoMap;
183 0 : if (!_sExtensionId.isEmpty())
184 : {
185 0 : std::vector<uno::Reference<deployment::XPackage> > vecExtensions;
186 0 : uno::Reference<deployment::XPackage> extension;
187 : try
188 : {
189 0 : extension = dp_misc::getExtensionWithHighestVersion(
190 0 : extMgr->getExtensionsWithSameIdentifier(
191 0 : _sExtensionId, _sExtensionId, uno::Reference<css_ucb::XCommandEnvironment>()));
192 0 : vecExtensions.push_back(extension);
193 : }
194 0 : catch (lang::IllegalArgumentException &)
195 : {
196 : OSL_ASSERT(false);
197 : }
198 0 : updateInfoMap = dp_misc::getOnlineUpdateInfos(
199 0 : mxContext, extMgr, mxUpdateInformation, &vecExtensions, errors);
200 : }
201 : else
202 : {
203 0 : updateInfoMap = dp_misc::getOnlineUpdateInfos(
204 0 : mxContext, extMgr, mxUpdateInformation, NULL, errors);
205 : }
206 :
207 0 : int nCount = 0;
208 0 : for (dp_misc::UpdateInfoMap::iterator i(updateInfoMap.begin()); i != updateInfoMap.end(); ++i)
209 : {
210 0 : dp_misc::UpdateInfo const & info = i->second;
211 :
212 0 : OUString sOnlineVersion;
213 0 : if (info.info.is())
214 : {
215 : // check, if there are unsatisfied dependencies and ignore this online update
216 0 : dp_misc::DescriptionInfoset infoset(mxContext, info.info);
217 : uno::Sequence< uno::Reference< xml::dom::XElement > >
218 0 : ds( dp_misc::Dependencies::check( infoset ) );
219 0 : if ( ! ds.getLength() )
220 0 : sOnlineVersion = info.version;
221 : }
222 :
223 0 : OUString sVersionUser;
224 0 : OUString sVersionShared;
225 0 : OUString sVersionBundled;
226 0 : uno::Sequence< uno::Reference< deployment::XPackage> > extensions;
227 : try {
228 0 : extensions = extMgr->getExtensionsWithSameIdentifier(
229 0 : dp_misc::getIdentifier(info.extension), info.extension->getName(),
230 0 : uno::Reference<css_ucb::XCommandEnvironment>());
231 0 : } catch (const lang::IllegalArgumentException& e) {
232 : SAL_WARN(
233 : "desktop.deployment",
234 : "ignoring IllegalArgumentException \"" << e.Message << "\"");
235 0 : continue;
236 : }
237 : OSL_ASSERT(extensions.getLength() == 3);
238 0 : if (extensions[0].is() )
239 0 : sVersionUser = extensions[0]->getVersion();
240 0 : if (extensions[1].is() )
241 0 : sVersionShared = extensions[1]->getVersion();
242 0 : if (extensions[2].is() )
243 0 : sVersionBundled = extensions[2]->getVersion();
244 :
245 0 : bool bSharedReadOnly = extMgr->isReadOnlyRepository("shared");
246 :
247 : dp_misc::UPDATE_SOURCE sourceUser = dp_misc::isUpdateUserExtension(
248 0 : bSharedReadOnly, sVersionUser, sVersionShared, sVersionBundled, sOnlineVersion);
249 : dp_misc::UPDATE_SOURCE sourceShared = dp_misc::isUpdateSharedExtension(
250 0 : bSharedReadOnly, sVersionShared, sVersionBundled, sOnlineVersion);
251 :
252 0 : OUString updateVersionUser;
253 0 : OUString updateVersionShared;
254 0 : if (sourceUser != dp_misc::UPDATE_SOURCE_NONE)
255 0 : updateVersionUser = dp_misc::getHighestVersion(
256 0 : OUString(), sVersionShared, sVersionBundled, sOnlineVersion);
257 0 : if (sourceShared != dp_misc::UPDATE_SOURCE_NONE)
258 0 : updateVersionShared = dp_misc::getHighestVersion(
259 0 : OUString(), OUString(), sVersionBundled, sOnlineVersion);
260 0 : OUString updateVersion;
261 0 : if (dp_misc::compareVersions(updateVersionUser, updateVersionShared) == dp_misc::GREATER)
262 0 : updateVersion = updateVersionUser;
263 : else
264 0 : updateVersion = updateVersionShared;
265 0 : if (!updateVersion.isEmpty())
266 : {
267 :
268 0 : OUString aNewEntry[2];
269 0 : aNewEntry[0] = i->first;
270 0 : aNewEntry[1] = updateVersion;
271 0 : aList.realloc( ++nCount );
272 0 : aList[ nCount-1 ] = ::uno::Sequence< OUString >( aNewEntry, 2 );
273 : }
274 0 : }
275 0 : return aList;
276 : }
277 :
278 :
279 0 : uno::Sequence< uno::Sequence< OUString > > SAL_CALL PackageInformationProvider::getExtensionList()
280 : throw ( uno::RuntimeException, std::exception )
281 : {
282 : const uno::Reference<deployment::XExtensionManager> mgr =
283 0 : deployment::ExtensionManager::get(mxContext);
284 :
285 0 : if (!mgr.is())
286 0 : return uno::Sequence< uno::Sequence< OUString > >();
287 :
288 : const uno::Sequence< uno::Sequence< uno::Reference<deployment::XPackage > > >
289 0 : allExt = mgr->getAllExtensions(
290 : uno::Reference< task::XAbortChannel >(),
291 0 : uno::Reference< css_ucb::XCommandEnvironment > () );
292 :
293 0 : uno::Sequence< uno::Sequence< OUString > > retList;
294 :
295 0 : sal_Int32 cAllIds = allExt.getLength();
296 0 : retList.realloc(cAllIds);
297 :
298 0 : for (sal_Int32 i = 0; i < cAllIds; i++)
299 : {
300 : //The inner sequence contains extensions with the same identifier from
301 : //all the different repositories, that is user, share, bundled.
302 : const uno::Sequence< uno::Reference< deployment::XPackage > > &
303 0 : seqExtension = allExt[i];
304 0 : sal_Int32 cExt = seqExtension.getLength();
305 : OSL_ASSERT(cExt == 3);
306 0 : for (sal_Int32 j = 0; j < cExt; j++)
307 : {
308 : //ToDo according to the old code the first found extenions is used
309 : //even if another one with the same id has a better version.
310 0 : uno::Reference< deployment::XPackage > const & xExtension( seqExtension[j] );
311 0 : if (xExtension.is())
312 : {
313 0 : OUString aNewEntry[2];
314 0 : aNewEntry[0] = dp_misc::getIdentifier(xExtension);
315 0 : aNewEntry[1] = xExtension->getVersion();
316 0 : retList[i] = ::uno::Sequence< OUString >( aNewEntry, 2 );
317 0 : break;
318 : }
319 : }
320 : }
321 0 : return retList;
322 : }
323 :
324 :
325 :
326 :
327 : namespace sdecl = comphelper::service_decl;
328 140 : sdecl::class_<PackageInformationProvider> servicePIP;
329 140 : extern sdecl::ServiceDecl const serviceDecl(
330 : servicePIP,
331 : // a private one:
332 : "com.sun.star.comp.deployment.PackageInformationProvider",
333 : "com.sun.star.comp.deployment.PackageInformationProvider" );
334 :
335 420 : } // namespace dp_info
336 :
337 :
338 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|