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