Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <cppuhelper/implbase1.hxx>
31 : :
32 : : #include "comphelper/servicedecl.hxx"
33 : : #include "cppuhelper/exc_hlp.hxx"
34 : : #include "rtl/bootstrap.hxx"
35 : : #include "com/sun/star/deployment/ExtensionManager.hpp"
36 : : #include "com/sun/star/deployment/XExtensionManager.hpp"
37 : : #include "com/sun/star/deployment/thePackageManagerFactory.hpp"
38 : : #include "com/sun/star/deployment/XPackageManager.hpp"
39 : : #include "com/sun/star/deployment/XPackageManagerFactory.hpp"
40 : : #include "com/sun/star/deployment/XPackage.hpp"
41 : : #include "com/sun/star/deployment/InstallException.hpp"
42 : : #include "com/sun/star/deployment/VersionException.hpp"
43 : : #include "com/sun/star/deployment/LicenseException.hpp"
44 : : #include "com/sun/star/lang/XServiceInfo.hpp"
45 : : #include "com/sun/star/registry/XRegistryKey.hpp"
46 : : #include "com/sun/star/beans/Optional.hpp"
47 : : #include "com/sun/star/task/XInteractionApprove.hpp"
48 : : #include "com/sun/star/beans/Ambiguous.hpp"
49 : : #include "com/sun/star/uno/XComponentContext.hpp"
50 : : #include "com/sun/star/io/XInputStream.hpp"
51 : : #include "com/sun/star/util/XModifyBroadcaster.hpp"
52 : : #include "comphelper/sequence.hxx"
53 : : #include "xmlscript/xml_helper.hxx"
54 : : #include "osl/diagnose.h"
55 : : #include "dp_interact.h"
56 : : #include "dp_resource.h"
57 : : #include "dp_ucb.h"
58 : : #include "dp_identifier.hxx"
59 : : #include "dp_descriptioninfoset.hxx"
60 : : #include "dp_extensionmanager.hxx"
61 : : #include "dp_commandenvironments.hxx"
62 : : #include "dp_properties.hxx"
63 : : #include "boost/bind.hpp"
64 : :
65 : : #include <list>
66 : : #include <boost/unordered_map.hpp>
67 : : #include <algorithm>
68 : :
69 : : namespace deploy = com::sun::star::deployment;
70 : : namespace lang = com::sun::star::lang;
71 : : namespace registry = com::sun::star::registry;
72 : : namespace task = com::sun::star::task;
73 : : namespace ucb = com::sun::star::ucb;
74 : : namespace uno = com::sun::star::uno;
75 : : namespace beans = com::sun::star::beans;
76 : : namespace util = com::sun::star::util;
77 : : namespace css = com::sun::star;
78 : :
79 : : using ::com::sun::star::uno::Reference;
80 : : using ::rtl::OUString;
81 : :
82 : : namespace {
83 : :
84 : : struct CompIdentifiers
85 : : {
86 : 2108 : bool operator() (::std::vector<Reference<deploy::XPackage> > const & a,
87 : : ::std::vector<Reference<deploy::XPackage> > const & b)
88 : : {
89 [ + - ][ + + ]: 2108 : if (getName(a).compareTo(getName(b)) < 0)
90 : 1116 : return true;
91 : 2108 : return false;
92 : : }
93 : :
94 : : OUString getName(::std::vector<Reference<deploy::XPackage> > const & a);
95 : : };
96 : :
97 : 4216 : OUString CompIdentifiers::getName(::std::vector<Reference<deploy::XPackage> > const & a)
98 : : {
99 : : OSL_ASSERT(a.size() == 3);
100 : : //get the first non-null reference
101 : 4216 : Reference<deploy::XPackage> extension;
102 : 4216 : ::std::vector<Reference<deploy::XPackage> >::const_iterator it = a.begin();
103 [ + - ][ + - ]: 12648 : for (; it != a.end(); ++it)
104 : : {
105 [ + + ]: 12648 : if (it->is())
106 : : {
107 [ + - ]: 4216 : extension = *it;
108 : 4216 : break;
109 : : }
110 : : }
111 : : OSL_ASSERT(extension.is());
112 [ + - ][ + - ]: 4216 : return extension->getDisplayName();
113 : : }
114 : :
115 : 124 : void writeLastModified(OUString & url, Reference<ucb::XCommandEnvironment> const & xCmdEnv)
116 : : {
117 : : //Write the lastmodified file
118 : : try {
119 : 124 : ::rtl::Bootstrap::expandMacros(url);
120 [ + - ]: 124 : ::ucbhelper::Content ucbStamp(url, xCmdEnv );
121 [ + - ]: 124 : dp_misc::erase_path( url, xCmdEnv );
122 : 124 : ::rtl::OString stamp("1" );
123 : : Reference<css::io::XInputStream> xData(
124 : : ::xmlscript::createInputStream(
125 : : ::rtl::ByteSequence(
126 : 124 : reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
127 [ + - ][ + - ]: 248 : stamp.getLength() ) ) );
128 [ + - ][ + - ]: 124 : ucbStamp.writeStream( xData, true /* replace existing */ );
129 : : }
130 : 0 : catch(...)
131 : : {
132 [ # # ]: 0 : uno::Any exc(::cppu::getCaughtException());
133 : : throw deploy::DeploymentException(
134 [ # # # # : 0 : OUSTR("Failed to update") + url, 0, exc);
# # ]
135 : : }
136 : 124 : }
137 : :
138 : : class ExtensionRemoveGuard
139 : : {
140 : : css::uno::Reference<css::deployment::XPackage> m_extension;
141 : : css::uno::Reference<css::deployment::XPackageManager> m_xPackageManager;
142 : :
143 : : public:
144 : 2 : ExtensionRemoveGuard(
145 : : css::uno::Reference<css::deployment::XPackage> const & extension,
146 : : css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager):
147 : 2 : m_extension(extension), m_xPackageManager(xPackageManager) {}
148 : : ~ExtensionRemoveGuard();
149 : :
150 : 0 : void reset(css::uno::Reference<css::deployment::XPackage> const & extension) {
151 : 0 : m_extension = extension;
152 : 0 : }
153 : : };
154 : :
155 : 2 : ExtensionRemoveGuard::~ExtensionRemoveGuard()
156 : : {
157 : : try {
158 [ + - ][ + - ]: 2 : if (m_xPackageManager.is() && m_extension.is())
[ + - ]
159 [ + - ]: 2 : m_xPackageManager->removePackage(
160 : : dp_misc::getIdentifier(m_extension), ::rtl::OUString(),
161 : : css::uno::Reference<css::task::XAbortChannel>(),
162 [ + - ][ + - ]: 2 : css::uno::Reference<css::ucb::XCommandEnvironment>());
163 [ # # ]: 0 : } catch (...) {
164 : : OSL_ASSERT(0);
165 : : }
166 : 2 : }
167 : :
168 : : }
169 : :
170 : : namespace dp_manager {
171 : :
172 : : //------------------------------------------------------------------------------
173 : :
174 : : //ToDo: bundled extension
175 : 124 : ExtensionManager::ExtensionManager( Reference< uno::XComponentContext > const& xContext) :
176 : 124 : ::cppu::WeakComponentImplHelper1< css::deployment::XExtensionManager >(getMutex()),
177 [ + - ][ + - ]: 248 : m_xContext( xContext )
178 : : {
179 [ + - ][ + - ]: 124 : m_xPackageManagerFactory = deploy::thePackageManagerFactory::get(m_xContext);
180 : : OSL_ASSERT(m_xPackageManagerFactory.is());
181 : :
182 [ + - ][ + - ]: 124 : m_repositoryNames.push_back(OUSTR("user"));
183 [ + - ][ + - ]: 124 : m_repositoryNames.push_back(OUSTR("shared"));
184 [ + - ][ + - ]: 124 : m_repositoryNames.push_back(OUSTR("bundled"));
185 : 124 : }
186 : :
187 : : //------------------------------------------------------------------------------
188 : :
189 [ + - ][ + - ]: 124 : ExtensionManager::~ExtensionManager()
190 : : {
191 [ - + ]: 124 : }
192 : :
193 : 368 : Reference<deploy::XPackageManager> ExtensionManager::getUserRepository()
194 : : {
195 [ + - ]: 368 : return m_xPackageManagerFactory->getPackageManager(OUSTR("user"));
196 : : }
197 : 426 : Reference<deploy::XPackageManager> ExtensionManager::getSharedRepository()
198 : : {
199 [ + - ]: 426 : return m_xPackageManagerFactory->getPackageManager(OUSTR("shared"));
200 : : }
201 : 426 : Reference<deploy::XPackageManager> ExtensionManager::getBundledRepository()
202 : : {
203 [ + - ]: 426 : return m_xPackageManagerFactory->getPackageManager(OUSTR("bundled"));
204 : : }
205 : 8 : Reference<deploy::XPackageManager> ExtensionManager::getTmpRepository()
206 : : {
207 [ + - ]: 8 : return m_xPackageManagerFactory->getPackageManager(OUSTR("tmp"));
208 : : }
209 : :
210 : 0 : Reference<task::XAbortChannel> ExtensionManager::createAbortChannel()
211 : : throw (uno::RuntimeException)
212 : : {
213 [ # # ][ # # ]: 0 : return new dp_misc::AbortChannel;
214 : : }
215 : :
216 : : css::uno::Reference<css::deployment::XPackageManager>
217 : 696 : ExtensionManager::getPackageManager(::rtl::OUString const & repository)
218 : : throw (css::lang::IllegalArgumentException)
219 : : {
220 : 696 : Reference<deploy::XPackageManager> xPackageManager;
221 [ + + ][ + - ]: 696 : if (repository.equals(OUSTR("user")))
222 [ + - ][ + - ]: 232 : xPackageManager = getUserRepository();
223 [ + - ][ + + ]: 464 : else if (repository.equals(OUSTR("shared")))
224 [ + - ][ + - ]: 232 : xPackageManager = getSharedRepository();
225 [ + - ][ + - ]: 232 : else if (repository.equals(OUSTR("bundled")))
226 [ + - ][ + - ]: 232 : xPackageManager = getBundledRepository();
227 : : else
228 : : throw lang::IllegalArgumentException(
229 : : OUSTR("No valid repository name provided."),
230 [ # # ][ # # ]: 0 : static_cast<cppu::OWeakObject*>(this), 0);
[ # # ]
231 : 696 : return xPackageManager;
232 : : }
233 : :
234 : : /*
235 : : Enters the XPackage objects into a map. They must be all from the
236 : : same repository. The value type of the map is a vector, where each vector
237 : : represents an extension with a particular identifier. The first member
238 : : represents the user extension, the second the shared extension and the
239 : : third the bundled extension.
240 : : */
241 : 372 : void ExtensionManager::addExtensionsToMap(
242 : : id2extensions & mapExt,
243 : : uno::Sequence<Reference<deploy::XPackage> > const & seqExt,
244 : : OUString const & repository)
245 : : {
246 : : //Determine the index in the vector where these extensions are to be
247 : : //added.
248 : : ::std::list<OUString>::const_iterator citNames =
249 : 372 : m_repositoryNames.begin();
250 : 372 : int index = 0;
251 [ + - ]: 744 : for (;citNames != m_repositoryNames.end(); ++citNames, ++index)
252 : : {
253 [ + + ]: 744 : if (citNames->equals(repository))
254 : 372 : break;
255 : : }
256 : :
257 [ + + ]: 1364 : for (int i = 0; i < seqExt.getLength(); ++i)
258 : : {
259 : 992 : Reference<deploy::XPackage> const & xExtension = seqExt[i];
260 [ + - ]: 992 : OUString id = dp_misc::getIdentifier(xExtension);
261 [ + - ]: 992 : id2extensions::iterator ivec = mapExt.find(id);
262 [ + - ][ + - ]: 992 : if (ivec == mapExt.end())
263 : : {
264 [ + - ]: 992 : ::std::vector<Reference<deploy::XPackage> > vec(3);
265 [ + - ]: 992 : vec[index] = xExtension;
266 [ + - ][ + - ]: 992 : mapExt[id] = vec;
267 : : }
268 : : else
269 : : {
270 [ # # ][ # # ]: 0 : ivec->second[index] = xExtension;
271 : : }
272 : 992 : }
273 : 372 : }
274 : :
275 : : /*
276 : : returns a list containing extensions with the same identifier from
277 : : all repositories (user, shared, bundled). If one repository does not
278 : : have this extension, then the list contains an empty Reference. The list
279 : : is ordered according to the priority of the repostories:
280 : : 1. user
281 : : 2. shared
282 : : 3. bundled
283 : :
284 : : The number of elements is always three, unless the number of repository
285 : : changes.
286 : : */
287 : : ::std::list<Reference<deploy::XPackage> >
288 : 8 : ExtensionManager::getExtensionsWithSameId(
289 : : OUString const & identifier, OUString const & fileName,
290 : : Reference< ucb::XCommandEnvironment> const & /*xCmdEnv*/)
291 : :
292 : : {
293 [ + - ]: 8 : ::std::list<Reference<deploy::XPackage> > extensionList;
294 : : Reference<deploy::XPackageManager> lRepos[] = {
295 [ + - ][ + - ]: 32 : getUserRepository(), getSharedRepository(), getBundledRepository() };
[ + - ]
[ # # # # ]
296 [ + + ]: 32 : for (int i(0); i != SAL_N_ELEMENTS(lRepos); ++i)
297 : : {
298 : 24 : Reference<deploy::XPackage> xPackage;
299 : : try
300 : : {
301 [ + - ]: 24 : xPackage = lRepos[i]->getDeployedPackage(
302 [ + + ][ + - ]: 24 : identifier, fileName, Reference<ucb::XCommandEnvironment>());
[ - + ]
303 : : }
304 [ + - ]: 20 : catch(const lang::IllegalArgumentException &)
305 : : {
306 : : // thrown if the extension does not exist in this repository
307 : : }
308 [ + - ]: 24 : extensionList.push_back(xPackage);
309 : 24 : }
310 : : OSL_ASSERT(extensionList.size() == 3);
311 [ + + ][ # # ]: 32 : return extensionList;
312 : : }
313 : :
314 : : uno::Sequence<Reference<deploy::XPackage> >
315 : 0 : ExtensionManager::getExtensionsWithSameIdentifier(
316 : : OUString const & identifier,
317 : : OUString const & fileName,
318 : : Reference< ucb::XCommandEnvironment> const & xCmdEnv )
319 : : throw (
320 : : deploy::DeploymentException,
321 : : ucb::CommandFailedException,
322 : : lang::IllegalArgumentException,
323 : : uno::RuntimeException)
324 : : {
325 : : try
326 : : {
327 : : ::std::list<Reference<deploy::XPackage> > listExtensions =
328 : : getExtensionsWithSameId(
329 [ # # ]: 0 : identifier, fileName, xCmdEnv);
330 : 0 : sal_Bool bHasExtension = false;
331 : :
332 : : //throw an IllegalArgumentException if there is no extension at all.
333 : : typedef ::std::list<Reference<deploy::XPackage> >::const_iterator CIT;
334 [ # # ]: 0 : for (CIT i = listExtensions.begin(); i != listExtensions.end(); ++i)
335 : 0 : bHasExtension |= i->is();
336 [ # # ]: 0 : if (!bHasExtension)
337 : : throw lang::IllegalArgumentException(
338 : : OUSTR("Could not find extension: ") + identifier + OUSTR(", ") + fileName,
339 [ # # ][ # # ]: 0 : static_cast<cppu::OWeakObject*>(this), -1);
[ # # ][ # # ]
340 : :
341 : : return comphelper::containerToSequence<
342 : : Reference<deploy::XPackage>,
343 : : ::std::list<Reference<deploy::XPackage> >
344 [ # # ]: 0 : > (listExtensions);
345 : : }
346 : 0 : catch ( const deploy::DeploymentException & )
347 : : {
348 : 0 : throw;
349 : : }
350 : 0 : catch ( const ucb::CommandFailedException & )
351 : : {
352 : 0 : throw;
353 : : }
354 : 0 : catch (const lang::IllegalArgumentException &)
355 : : {
356 : 0 : throw;
357 : : }
358 [ # # # # ]: 0 : catch (...)
359 : : {
360 [ # # ]: 0 : uno::Any exc = ::cppu::getCaughtException();
361 : : throw deploy::DeploymentException(
362 : : OUSTR("Extension Manager: exception during getExtensionsWithSameIdentifier"),
363 [ # # # # : 0 : static_cast<OWeakObject*>(this), exc);
# # ]
364 : : }
365 : : }
366 : :
367 : 4 : bool ExtensionManager::isUserDisabled(
368 : : OUString const & identifier, OUString const & fileName)
369 : : {
370 [ + - ]: 4 : ::std::list<Reference<deploy::XPackage> > listExtensions;
371 : :
372 : : try {
373 [ + - ][ + - ]: 4 : listExtensions = getExtensionsWithSameId(identifier, fileName);
[ # # ]
374 [ # # ]: 0 : } catch ( const lang::IllegalArgumentException & ) {
375 : : }
376 : : OSL_ASSERT(listExtensions.size() == 3);
377 : :
378 : : return isUserDisabled( ::comphelper::containerToSequence<
379 : : Reference<deploy::XPackage>,
380 : : ::std::list<Reference<deploy::XPackage> >
381 [ + - ][ + - ]: 4 : > (listExtensions));
[ + - ]
382 : : }
383 : :
384 : 500 : bool ExtensionManager::isUserDisabled(
385 : : uno::Sequence<Reference<deploy::XPackage> > const & seqExtSameId)
386 : : {
387 : : OSL_ASSERT(seqExtSameId.getLength() == 3);
388 : 500 : Reference<deploy::XPackage> const & userExtension = seqExtSameId[0];
389 [ + + ]: 500 : if (userExtension.is())
390 : : {
391 : : beans::Optional<beans::Ambiguous<sal_Bool> > reg =
392 [ + - ]: 2 : userExtension->isRegistered(Reference<task::XAbortChannel>(),
393 [ + - ]: 2 : Reference<ucb::XCommandEnvironment>());
394 : : //If the value is ambiguous is than we assume that the extension
395 : : //is enabled, but something went wrong during enabling. We do not
396 : : //automatically disable user extensions.
397 [ + - ][ - + ]: 2 : if (reg.IsPresent &&
[ + - ]
398 : 4 : ! reg.Value.IsAmbiguous && ! reg.Value.Value)
399 : 2 : return true;
400 : : }
401 : 500 : return false;
402 : : }
403 : :
404 : : /*
405 : : This method determines the active extension (XPackage.registerPackage) with a
406 : : particular identifier.
407 : :
408 : : The parameter bUserDisabled determines if the user extension is disabled.
409 : :
410 : : When the user repository contains an extension with the given identifier and
411 : : it is not disabled by the user, then it is always registered. Otherwise an
412 : : extension is only registered when there is no registered extension in one of
413 : : the repositories with a higher priority. That is, if the extension is from
414 : : the shared repository and an active extension with the same identifer is in
415 : : the user repository, then the extension is not registered. Similarly a
416 : : bundled extension is not registered if there is an active extension with the
417 : : same identifier in the shared or user repository.
418 : : */
419 : 4 : void ExtensionManager::activateExtension(
420 : : OUString const & identifier, OUString const & fileName,
421 : : bool bUserDisabled,
422 : : bool bStartup,
423 : : Reference<task::XAbortChannel> const & xAbortChannel,
424 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
425 : : {
426 [ + - ]: 4 : ::std::list<Reference<deploy::XPackage> > listExtensions;
427 : : try {
428 [ + - ][ + - ]: 4 : listExtensions = getExtensionsWithSameId(identifier, fileName);
[ # # ]
429 [ # # ]: 0 : } catch (const lang::IllegalArgumentException &) {
430 : : }
431 : : OSL_ASSERT(listExtensions.size() == 3);
432 : :
433 : : activateExtension(
434 : : ::comphelper::containerToSequence<
435 : : Reference<deploy::XPackage>,
436 : : ::std::list<Reference<deploy::XPackage> >
437 : : > (listExtensions),
438 [ + - ][ + - ]: 4 : bUserDisabled, bStartup, xAbortChannel, xCmdEnv);
[ + - ]
439 : :
440 [ + - ]: 4 : fireModified();
441 : 4 : }
442 : :
443 : 500 : void ExtensionManager::activateExtension(
444 : : uno::Sequence<Reference<deploy::XPackage> > const & seqExt,
445 : : bool bUserDisabled,
446 : : bool bStartup,
447 : : Reference<task::XAbortChannel> const & xAbortChannel,
448 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
449 : : {
450 : 500 : bool bActive = false;
451 : 500 : sal_Int32 len = seqExt.getLength();
452 [ + + ]: 2000 : for (sal_Int32 i = 0; i < len; i++)
453 : : {
454 : 1500 : Reference<deploy::XPackage> const & aExt = seqExt[i];
455 [ + + ]: 1500 : if (aExt.is())
456 : : {
457 : : //get the registration value of the current iteration
458 : : beans::Optional<beans::Ambiguous<sal_Bool> > optReg =
459 [ + - ][ + - ]: 498 : aExt->isRegistered(xAbortChannel, xCmdEnv);
460 : : //If nothing can be registered then break
461 [ + - ]: 498 : if (!optReg.IsPresent)
462 : : break;
463 : :
464 : : //Check if this is a disabled user extension,
465 [ + + ][ - + ]: 498 : if (i == 0 && bUserDisabled)
466 : : {
467 [ # # ][ # # ]: 0 : aExt->revokePackage(bStartup, xAbortChannel, xCmdEnv);
468 : 0 : continue;
469 : : }
470 : :
471 : : //If we have already determined an active extension then we must
472 : : //make sure to unregister all extensions with the same id in
473 : : //repositories with a lower priority
474 [ - + ]: 498 : if (bActive)
475 : : {
476 [ # # ][ # # ]: 0 : aExt->revokePackage(bStartup, xAbortChannel, xCmdEnv);
477 : : }
478 : : else
479 : : {
480 : : //This is the first extension in the ordered list, which becomes
481 : : //the active extension
482 : 498 : bActive = true;
483 : : //Register if not already done.
484 : : //reregister if the value is ambiguous, which indicates that
485 : : //something went wrong during last registration.
486 [ + - ][ + - ]: 498 : aExt->registerPackage(bStartup, xAbortChannel, xCmdEnv);
487 : : }
488 : : }
489 : : }
490 : 500 : }
491 : :
492 : 2 : Reference<deploy::XPackage> ExtensionManager::backupExtension(
493 : : OUString const & identifier, OUString const & fileName,
494 : : Reference<deploy::XPackageManager> const & xPackageManager,
495 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
496 : : {
497 : 2 : Reference<deploy::XPackage> xBackup;
498 : : Reference<ucb::XCommandEnvironment> tmpCmdEnv(
499 [ + - ][ + - ]: 2 : new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
[ + - ][ + - ]
[ + - ]
500 : 2 : Reference<deploy::XPackage> xOldExtension;
501 [ + - ]: 2 : xOldExtension = xPackageManager->getDeployedPackage(
502 [ + - ][ + - ]: 2 : identifier, fileName, tmpCmdEnv);
503 : :
504 [ + - ]: 2 : if (xOldExtension.is())
505 : : {
506 [ + - ][ + - ]: 4 : xBackup = getTmpRepository()->addPackage(
507 [ + - ]: 2 : xOldExtension->getURL(), uno::Sequence<beans::NamedValue>(),
508 [ + - ][ + - ]: 4 : OUString(), Reference<task::XAbortChannel>(), tmpCmdEnv);
[ + - ][ + - ]
[ + - ]
509 : :
510 : : OSL_ENSURE(xBackup.is(), "Failed to backup extension");
511 : : }
512 : 2 : return xBackup;
513 : : }
514 : :
515 : : //The supported package types are actually determined by the registry. However
516 : : //creating a registry
517 : : //(desktop/source/deployment/registry/dp_registry.cxx:PackageRegistryImpl) will
518 : : //create all the backends, so that the registry can obtain from them the package
519 : : //types. Creating the registry will also set up the registry folder containing
520 : : //all the subfolders for the respective backends.
521 : : //Because all repositories support the same backends, we can just delegate this
522 : : //call to one of the repositories.
523 : : uno::Sequence< Reference<deploy::XPackageTypeInfo> >
524 : 0 : ExtensionManager::getSupportedPackageTypes()
525 : : throw (uno::RuntimeException)
526 : : {
527 [ # # ][ # # ]: 0 : return getUserRepository()->getSupportedPackageTypes();
528 : : }
529 : : //Do some necessary checks and user interaction. This function does not
530 : : //aquire the extension manager mutex and that mutex must not be aquired
531 : : //when this function is called. doChecksForAddExtension does synchronous
532 : : //user interactions which may require aquiring the solar mutex.
533 : : //Returns true if the extension can be installed.
534 : 2 : bool ExtensionManager::doChecksForAddExtension(
535 : : Reference<deploy::XPackageManager> const & xPackageMgr,
536 : : uno::Sequence<beans::NamedValue> const & properties,
537 : : css::uno::Reference<css::deployment::XPackage> const & xTmpExtension,
538 : : Reference<task::XAbortChannel> const & xAbortChannel,
539 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv,
540 : : Reference<deploy::XPackage> & out_existingExtension )
541 : : throw (deploy::DeploymentException,
542 : : ucb::CommandFailedException,
543 : : ucb::CommandAbortedException,
544 : : lang::IllegalArgumentException,
545 : : uno::RuntimeException)
546 : : {
547 : : try
548 : : {
549 : 2 : Reference<deploy::XPackage> xOldExtension;
550 [ + - ]: 2 : const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
551 [ + - ][ + - ]: 2 : const OUString sFileName = xTmpExtension->getName();
552 [ + - ][ + - ]: 2 : const OUString sDisplayName = xTmpExtension->getDisplayName();
553 [ + - ][ + - ]: 2 : const OUString sVersion = xTmpExtension->getVersion();
554 : :
555 : : try
556 : : {
557 [ + - ]: 2 : xOldExtension = xPackageMgr->getDeployedPackage(
558 [ - + ][ # # ]: 2 : sIdentifier, sFileName, xCmdEnv);
[ - + ]
559 [ # # ]: 0 : out_existingExtension = xOldExtension;
560 : : }
561 [ + - ]: 2 : catch (const lang::IllegalArgumentException &)
562 : : {
563 : : }
564 : 2 : bool bCanInstall = false;
565 : :
566 : : //This part is not guarded against other threads removing, adding, disabling ...
567 : : //etc. the same extension.
568 : : //checkInstall is safe because it notifies the user if the extension is not yet
569 : : //installed in the same repository. Because addExtension has its own guard
570 : : //(m_addMutex), another thread cannot add the extension in the meantime.
571 : : //checkUpdate is called if the same extension exists in the same
572 : : //repository. The user is asked if they want to replace it. Another
573 : : //thread
574 : : //could already remove the extension. So asking the user was not
575 : : //necessary. No harm is done. The other thread may also ask the user
576 : : //if he wants to remove the extension. This depends on the
577 : : //XCommandEnvironment which it passes to removeExtension.
578 [ - + ]: 2 : if (xOldExtension.is())
579 : : {
580 : : //throws a CommandFailedException if the user cancels
581 : : //the action.
582 [ # # ]: 0 : checkUpdate(sVersion, sDisplayName,xOldExtension, xCmdEnv);
583 : : }
584 : : else
585 : : {
586 : : //throws a CommandFailedException if the user cancels
587 : : //the action.
588 [ + - ]: 2 : checkInstall(sDisplayName, xCmdEnv);
589 : : }
590 : : //Prevent showing the license if requested.
591 : 2 : Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
592 [ + - ]: 2 : ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>());
593 : :
594 [ + - ][ + - ]: 2 : dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL()));
[ + - ]
595 : : const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes =
596 [ + - ]: 2 : info.getSimpleLicenseAttributes();
597 : :
598 [ + - ][ - + ]: 2 : if (licenseAttributes && licenseAttributes->suppressIfRequired
[ # # ][ # # ]
[ # # ][ - + ]
599 [ # # ]: 0 : && props.isSuppressedLicense())
600 : : _xCmdEnv = Reference<ucb::XCommandEnvironment>(
601 [ # # ][ # # ]: 0 : new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler()));
[ # # ][ # # ]
[ # # ][ # # ]
602 : :
603 [ + - ]: 2 : bCanInstall = xTmpExtension->checkPrerequisites(
604 [ + - ][ + - ]: 2 : xAbortChannel, _xCmdEnv, xOldExtension.is() || props.isExtensionUpdate()) == 0 ? true : false;
[ - + ][ + - ]
605 : :
606 [ + - ][ + - ]: 2 : return bCanInstall;
[ + - ]
607 : : }
608 : 0 : catch ( const deploy::DeploymentException& ) {
609 : 0 : throw;
610 : 0 : } catch ( const ucb::CommandFailedException & ) {
611 : 0 : throw;
612 : 0 : } catch ( const ucb::CommandAbortedException & ) {
613 : 0 : throw;
614 : 0 : } catch (const lang::IllegalArgumentException &) {
615 : 0 : throw;
616 : 0 : } catch (const uno::RuntimeException &) {
617 : 0 : throw;
618 : 0 : } catch (const uno::Exception &) {
619 [ # # ]: 0 : uno::Any excOccurred = ::cppu::getCaughtException();
620 : : deploy::DeploymentException exc(
621 : : OUSTR("Extension Manager: exception in doChecksForAddExtension"),
622 [ # # # # : 0 : static_cast<OWeakObject*>(this), excOccurred);
# # ]
623 [ # # ]: 0 : throw exc;
624 [ # # # # : 0 : } catch (...) {
# # # ]
625 : : throw uno::RuntimeException(
626 : : OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
627 [ # # # # : 0 : static_cast<OWeakObject*>(this));
# # ]
628 : : }
629 : : }
630 : :
631 : : // Only add to shared and user repository
632 : 2 : Reference<deploy::XPackage> ExtensionManager::addExtension(
633 : : OUString const & url, uno::Sequence<beans::NamedValue> const & properties,
634 : : OUString const & repository,
635 : : Reference<task::XAbortChannel> const & xAbortChannel,
636 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
637 : : throw (deploy::DeploymentException,
638 : : ucb::CommandFailedException,
639 : : ucb::CommandAbortedException,
640 : : lang::IllegalArgumentException,
641 : : uno::RuntimeException)
642 : : {
643 : 2 : Reference<deploy::XPackage> xNewExtension;
644 : : //Determine the repository to use
645 : 2 : Reference<deploy::XPackageManager> xPackageManager;
646 [ + - ][ + - ]: 2 : if (repository.equals(OUSTR("user")))
647 [ + - ][ + - ]: 2 : xPackageManager = getUserRepository();
648 [ # # ][ # # ]: 0 : else if (repository.equals(OUSTR("shared")))
649 [ # # ][ # # ]: 0 : xPackageManager = getSharedRepository();
650 : : else
651 : : throw lang::IllegalArgumentException(
652 : : OUSTR("No valid repository name provided."),
653 [ # # ][ # # ]: 0 : static_cast<cppu::OWeakObject*>(this), 0);
[ # # ]
654 : : //We must make sure that the xTmpExtension is not create twice, because this
655 : : //would remove the first one.
656 [ + - ]: 2 : ::osl::MutexGuard addGuard(m_addMutex);
657 : :
658 : : Reference<deploy::XPackage> xTmpExtension =
659 [ + - ]: 2 : getTempExtension(url, xAbortChannel, xCmdEnv);
660 : : //Make sure the extension is removed from the tmp repository in case
661 : : //of an exception
662 [ + - ][ + - ]: 2 : ExtensionRemoveGuard tmpExtensionRemoveGuard(xTmpExtension, getTmpRepository());
663 [ + - ]: 2 : const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
664 [ + - ][ + - ]: 2 : const OUString sFileName = xTmpExtension->getName();
665 : 2 : Reference<deploy::XPackage> xOldExtension;
666 : 2 : Reference<deploy::XPackage> xExtensionBackup;
667 : :
668 : 2 : uno::Any excOccurred2;
669 : 2 : bool bUserDisabled = false;
670 : : bool bCanInstall = doChecksForAddExtension(
671 : : xPackageManager,
672 : : properties,
673 : : xTmpExtension,
674 : : xAbortChannel,
675 : : xCmdEnv,
676 [ + - ]: 2 : xOldExtension );
677 : :
678 : : {
679 : : // In this garded section (getMutex) we must not use the argument xCmdEnv
680 : : // because it may bring up dialogs (XInteractionHandler::handle) this
681 : : //may potententially deadlock. See issue
682 : : //http://qa.openoffice.org/issues/show_bug.cgi?id=114933
683 : : //By not providing xCmdEnv the underlying APIs will throw an exception if
684 : : //the XInteractionRequest cannot be handled
685 [ + - ]: 2 : ::osl::MutexGuard guard(getMutex());
686 : :
687 [ + - ]: 2 : if (bCanInstall)
688 : : {
689 : : try
690 : : {
691 [ + - ]: 2 : bUserDisabled = isUserDisabled(sIdentifier, sFileName);
692 [ - + ]: 2 : if (xOldExtension.is())
693 : : {
694 : : try
695 : : {
696 [ # # ]: 0 : xOldExtension->revokePackage(
697 [ # # ]: 0 : false, xAbortChannel, Reference<ucb::XCommandEnvironment>());
698 : : //save the old user extension in case the user aborts
699 : : //store the extension in the tmp repository, this will overwrite
700 : : //xTmpPackage (same identifier). Do not let the user abort or
701 : : //interact
702 : : //importing the old extension in the tmp repository will remove
703 : : //the xTmpExtension
704 : : //no command environment supplied, only this class shall interact
705 : : //with the user!
706 [ # # # # ]: 0 : xExtensionBackup = getTmpRepository()->importExtension(
[ # # ]
707 : : xOldExtension, Reference<task::XAbortChannel>(),
708 [ # # ][ # # ]: 0 : Reference<ucb::XCommandEnvironment>());
709 [ # # ]: 0 : tmpExtensionRemoveGuard.reset(xExtensionBackup);
710 : : //xTmpExtension will later be used to check the dependencies
711 : : //again. However, only xExtensionBackup will be later removed
712 : : //from the tmp repository
713 [ # # ]: 0 : xTmpExtension = xExtensionBackup;
714 : : OSL_ASSERT(xTmpExtension.is());
715 : : }
716 [ # # ]: 0 : catch (const lang::DisposedException &)
717 : : {
718 : : //Another thread might have removed the extension meanwhile
719 : : }
720 : : }
721 : : //check again dependencies but prevent user interaction,
722 : : //We can disregard the license, because the user must have already
723 : : //accepted it, when we called checkPrerequisites the first time
724 : : SilentCheckPrerequisitesCommandEnv * pSilentCommandEnv =
725 [ + - ]: 2 : new SilentCheckPrerequisitesCommandEnv();
726 [ + - ][ + - ]: 2 : Reference<ucb::XCommandEnvironment> silentCommandEnv(pSilentCommandEnv);
727 : :
728 [ + - ]: 2 : sal_Int32 failedPrereq = xTmpExtension->checkPrerequisites(
729 [ + - ]: 2 : xAbortChannel, silentCommandEnv, true);
730 [ + - ]: 2 : if (failedPrereq == 0)
731 : : {
732 [ + - ]: 2 : xNewExtension = xPackageManager->addPackage(
733 : : url, properties, OUString(), xAbortChannel,
734 [ + - ][ + - ]: 2 : Reference<ucb::XCommandEnvironment>());
735 : : //If we add a user extension and there is already one which was
736 : : //disabled by a user, then the newly installed one is enabled. If we
737 : : //add to another repository then the user extension remains
738 : : //disabled.
739 : 2 : bool bUserDisabled2 = bUserDisabled;
740 [ + - ][ + - ]: 2 : if (repository.equals(OUSTR("user")))
741 : 2 : bUserDisabled2 = false;
742 : :
743 : : // pass the two values via variables to workaround gcc-4.3.4 specific bug (bnc#655912)
744 [ + - ]: 2 : OUString sNewExtensionIdentifier = dp_misc::getIdentifier(xNewExtension);
745 [ + - ][ + - ]: 2 : OUString sNewExtensionFileName = xNewExtension->getName();
746 : :
747 : : activateExtension(
748 : : sNewExtensionIdentifier, sNewExtensionFileName,
749 : : bUserDisabled2, false, xAbortChannel,
750 [ + - ]: 2 : Reference<ucb::XCommandEnvironment>());
751 : : }
752 : : else
753 : : {
754 [ # # ]: 0 : if (pSilentCommandEnv->m_Exception.hasValue())
755 [ # # ]: 0 : ::cppu::throwException(pSilentCommandEnv->m_Exception);
756 [ # # ]: 0 : else if ( pSilentCommandEnv->m_UnknownException.hasValue())
757 [ # # ]: 0 : ::cppu::throwException(pSilentCommandEnv->m_UnknownException);
758 : : else
759 : : throw deploy::DeploymentException (
760 : : OUSTR("Extension Manager: exception during addExtension, ckeckPrerequisites failed"),
761 [ # # ][ # # ]: 0 : static_cast<OWeakObject*>(this), uno::Any());
[ # # ]
762 : 2 : }
763 : : }
764 [ # # ]: 0 : catch ( const deploy::DeploymentException& ) {
765 [ # # ]: 0 : excOccurred2 = ::cppu::getCaughtException();
766 [ # # ]: 0 : } catch ( const ucb::CommandFailedException & ) {
767 [ # # ]: 0 : excOccurred2 = ::cppu::getCaughtException();
768 [ # # ]: 0 : } catch ( const ucb::CommandAbortedException & ) {
769 [ # # ]: 0 : excOccurred2 = ::cppu::getCaughtException();
770 [ # # ]: 0 : } catch (const lang::IllegalArgumentException &) {
771 [ # # ]: 0 : excOccurred2 = ::cppu::getCaughtException();
772 [ # # ]: 0 : } catch (const uno::RuntimeException &) {
773 [ # # ]: 0 : excOccurred2 = ::cppu::getCaughtException();
774 [ # # # # : 0 : } catch (...) {
# # # # ]
775 [ # # ]: 0 : excOccurred2 = ::cppu::getCaughtException();
776 : : deploy::DeploymentException exc(
777 : : OUSTR("Extension Manager: exception during addExtension, url: ")
778 [ # # # # : 0 : + url, static_cast<OWeakObject*>(this), excOccurred2);
# # ]
779 [ # # # # ]: 0 : excOccurred2 <<= exc;
780 : : }
781 : : }
782 : :
783 [ - + ]: 2 : if (excOccurred2.hasValue())
784 : : {
785 : : //It does not matter what exception is thrown. We try to
786 : : //recover the original status.
787 : : //If the user aborted installation then a ucb::CommandAbortedException
788 : : //is thrown.
789 : : //Use a private AbortChannel so the user cannot interrupt.
790 : : try
791 : : {
792 [ # # ]: 0 : if (xExtensionBackup.is())
793 : : {
794 : : Reference<deploy::XPackage> xRestored =
795 [ # # ]: 0 : xPackageManager->importExtension(
796 : : xExtensionBackup, Reference<task::XAbortChannel>(),
797 [ # # ]: 0 : Reference<ucb::XCommandEnvironment>());
798 : : }
799 : : activateExtension(
800 : : sIdentifier, sFileName, bUserDisabled, false,
801 [ # # ]: 0 : Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
802 : : }
803 [ # # ]: 0 : catch (...)
804 : : {
805 : : }
806 [ # # ]: 0 : ::cppu::throwException(excOccurred2);
807 [ + - ]: 2 : }
808 : : } // leaving the garded section (getMutex())
809 : :
810 : : try
811 : : {
812 [ + - ]: 2 : fireModified();
813 : :
814 : 0 : }catch ( const deploy::DeploymentException& ) {
815 : 0 : throw;
816 : 0 : } catch ( const ucb::CommandFailedException & ) {
817 : 0 : throw;
818 : 0 : } catch ( const ucb::CommandAbortedException & ) {
819 : 0 : throw;
820 : 0 : } catch (const lang::IllegalArgumentException &) {
821 : 0 : throw;
822 : 0 : } catch (const uno::RuntimeException &) {
823 : 0 : throw;
824 : 0 : } catch (const uno::Exception &) {
825 [ # # ]: 0 : uno::Any excOccurred = ::cppu::getCaughtException();
826 : : deploy::DeploymentException exc(
827 : : OUSTR("Extension Manager: exception in doChecksForAddExtension"),
828 [ # # # # : 0 : static_cast<OWeakObject*>(this), excOccurred);
# # ]
829 [ # # ]: 0 : throw exc;
830 [ # # # # : 0 : } catch (...) {
# # # ]
831 : : throw uno::RuntimeException(
832 : : OUSTR("Extension Manager: unexpected exception in doChecksForAddExtension"),
833 [ # # # # : 0 : static_cast<OWeakObject*>(this));
# # ]
834 : : }
835 : :
836 [ + - ][ + - ]: 2 : return xNewExtension;
837 : : }
838 : :
839 : 2 : void ExtensionManager::removeExtension(
840 : : OUString const & identifier, OUString const & fileName,
841 : : OUString const & repository,
842 : : Reference<task::XAbortChannel> const & xAbortChannel,
843 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
844 : : throw (deploy::DeploymentException,
845 : : ucb::CommandFailedException,
846 : : ucb::CommandAbortedException,
847 : : lang::IllegalArgumentException,
848 : : uno::RuntimeException)
849 : : {
850 : 2 : uno::Any excOccurred1;
851 : 2 : Reference<deploy::XPackage> xExtensionBackup;
852 : 2 : Reference<deploy::XPackageManager> xPackageManager;
853 : 2 : bool bUserDisabled = false;
854 [ + - ]: 2 : ::osl::MutexGuard guard(getMutex());
855 : : try
856 : : {
857 : : //Determine the repository to use
858 [ + - ][ + - ]: 2 : if (repository.equals(OUSTR("user")))
859 [ + - ][ + - ]: 2 : xPackageManager = getUserRepository();
860 [ # # ][ # # ]: 0 : else if (repository.equals(OUSTR("shared")))
861 [ # # ][ # # ]: 0 : xPackageManager = getSharedRepository();
862 : : else
863 : : throw lang::IllegalArgumentException(
864 : : OUSTR("No valid repository name provided."),
865 [ # # ][ # # ]: 0 : static_cast<cppu::OWeakObject*>(this), 0);
[ # # ]
866 : :
867 [ + - ]: 2 : bUserDisabled = isUserDisabled(identifier, fileName);
868 : : //Backup the extension, in case the user cancels the action
869 : : xExtensionBackup = backupExtension(
870 [ + - ][ + - ]: 2 : identifier, fileName, xPackageManager, xCmdEnv);
871 : :
872 : : //revoke the extension if it is active
873 : : Reference<deploy::XPackage> xOldExtension =
874 [ + - ]: 2 : xPackageManager->getDeployedPackage(
875 [ + - ]: 2 : identifier, fileName, xCmdEnv);
876 [ + - ][ + - ]: 2 : xOldExtension->revokePackage(false, xAbortChannel, xCmdEnv);
877 : :
878 [ + - ]: 2 : xPackageManager->removePackage(
879 [ + - ]: 2 : identifier, fileName, xAbortChannel, xCmdEnv);
880 : : activateExtension(identifier, fileName, bUserDisabled, false,
881 [ + - ]: 2 : xAbortChannel, xCmdEnv);
882 [ + - ]: 2 : fireModified();
883 : : }
884 [ # # ]: 0 : catch ( const deploy::DeploymentException& ) {
885 [ # # ]: 0 : excOccurred1 = ::cppu::getCaughtException();
886 [ # # ]: 0 : } catch ( const ucb::CommandFailedException & ) {
887 [ # # ]: 0 : excOccurred1 = ::cppu::getCaughtException();
888 [ # # ]: 0 : } catch ( const ucb::CommandAbortedException & ) {
889 [ # # ]: 0 : excOccurred1 = ::cppu::getCaughtException();
890 [ # # ]: 0 : } catch (const lang::IllegalArgumentException &) {
891 [ # # ]: 0 : excOccurred1 = ::cppu::getCaughtException();
892 [ # # ]: 0 : } catch (const uno::RuntimeException &) {
893 [ # # ]: 0 : excOccurred1 = ::cppu::getCaughtException();
894 [ # # # # : 0 : } catch (...) {
# # # # ]
895 [ # # ]: 0 : excOccurred1 = ::cppu::getCaughtException();
896 : : deploy::DeploymentException exc(
897 : : OUSTR("Extension Manager: exception during removeEtension"),
898 [ # # # # : 0 : static_cast<OWeakObject*>(this), excOccurred1);
# # ]
899 [ # # # # ]: 0 : excOccurred1 <<= exc;
900 : : }
901 : :
902 [ - + ]: 2 : if (excOccurred1.hasValue())
903 : : {
904 : : //User aborted installation, restore the previous situation.
905 : : //Use a private AbortChannel so the user cannot interrupt.
906 : : try
907 : : {
908 : : Reference<ucb::XCommandEnvironment> tmpCmdEnv(
909 [ # # ][ # # ]: 0 : new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
[ # # ][ # # ]
[ # # ]
910 [ # # ]: 0 : if (xExtensionBackup.is())
911 : : {
912 : : Reference<deploy::XPackage> xRestored =
913 [ # # ]: 0 : xPackageManager->importExtension(
914 : : xExtensionBackup, Reference<task::XAbortChannel>(),
915 [ # # ]: 0 : tmpCmdEnv);
916 : : activateExtension(
917 : : identifier, fileName, bUserDisabled, false,
918 : : Reference<task::XAbortChannel>(),
919 [ # # ]: 0 : tmpCmdEnv);
920 : :
921 [ # # ][ # # ]: 0 : getTmpRepository()->removePackage(
922 : : dp_misc::getIdentifier(xExtensionBackup),
923 [ # # ][ # # ]: 0 : xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
[ # # ][ # # ]
924 [ # # ]: 0 : fireModified();
925 : 0 : }
926 : : }
927 [ # # ]: 0 : catch (...)
928 : : {
929 : : }
930 [ # # ]: 0 : ::cppu::throwException(excOccurred1);
931 : : }
932 : :
933 [ + - ]: 2 : if (xExtensionBackup.is())
934 [ + - ][ + - ]: 4 : getTmpRepository()->removePackage(
935 : : dp_misc::getIdentifier(xExtensionBackup),
936 [ + - ][ + - ]: 4 : xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
[ + - ][ + - ]
[ + - ]
937 : 2 : }
938 : :
939 : : // Only enable extensions from shared and user repository
940 : 0 : void ExtensionManager::enableExtension(
941 : : Reference<deploy::XPackage> const & extension,
942 : : Reference<task::XAbortChannel> const & xAbortChannel,
943 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv)
944 : : throw (deploy::DeploymentException,
945 : : ucb::CommandFailedException,
946 : : ucb::CommandAbortedException,
947 : : lang::IllegalArgumentException,
948 : : uno::RuntimeException)
949 : : {
950 [ # # ]: 0 : ::osl::MutexGuard guard(getMutex());
951 : 0 : bool bUserDisabled = false;
952 : 0 : uno::Any excOccurred;
953 : : try
954 : : {
955 [ # # ]: 0 : if (!extension.is())
956 : 0 : return;
957 [ # # ][ # # ]: 0 : OUString repository = extension->getRepositoryName();
958 [ # # ][ # # ]: 0 : if (!repository.equals(OUSTR("user")))
959 : : throw lang::IllegalArgumentException(
960 : : OUSTR("No valid repository name provided."),
961 [ # # ][ # # ]: 0 : static_cast<cppu::OWeakObject*>(this), 0);
[ # # ]
962 : :
963 : : bUserDisabled = isUserDisabled(dp_misc::getIdentifier(extension),
964 [ # # ][ # # ]: 0 : extension->getName());
[ # # ][ # # ]
965 : :
966 : : activateExtension(dp_misc::getIdentifier(extension),
967 [ # # ]: 0 : extension->getName(), false, false,
968 [ # # ][ # # ]: 0 : xAbortChannel, xCmdEnv);
[ # # ]
969 : : }
970 [ # # ]: 0 : catch ( const deploy::DeploymentException& ) {
971 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
972 [ # # ]: 0 : } catch ( const ucb::CommandFailedException & ) {
973 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
974 [ # # ]: 0 : } catch ( const ucb::CommandAbortedException & ) {
975 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
976 [ # # ]: 0 : } catch (const lang::IllegalArgumentException &) {
977 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
978 [ # # ]: 0 : } catch (const uno::RuntimeException &) {
979 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
980 [ # # # # : 0 : } catch (...) {
# # # # ]
981 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
982 : : deploy::DeploymentException exc(
983 : : OUSTR("Extension Manager: exception during enableExtension"),
984 [ # # # # : 0 : static_cast<OWeakObject*>(this), excOccurred);
# # ]
985 [ # # # # ]: 0 : excOccurred <<= exc;
986 : : }
987 : :
988 [ # # ]: 0 : if (excOccurred.hasValue())
989 : : {
990 : : try
991 : : {
992 : : activateExtension(dp_misc::getIdentifier(extension),
993 [ # # ]: 0 : extension->getName(), bUserDisabled, false,
994 [ # # ][ # # ]: 0 : xAbortChannel, xCmdEnv);
[ # # ]
995 : : }
996 [ # # ]: 0 : catch (...)
997 : : {
998 : : }
999 [ # # ]: 0 : ::cppu::throwException(excOccurred);
1000 [ # # ][ # # ]: 0 : }
[ # # ]
1001 : : }
1002 : :
1003 : : /**
1004 : : */
1005 : 0 : sal_Int32 ExtensionManager::checkPrerequisitesAndEnable(
1006 : : Reference<deploy::XPackage> const & extension,
1007 : : Reference<task::XAbortChannel> const & xAbortChannel,
1008 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv)
1009 : : throw (deploy::DeploymentException,
1010 : : ucb::CommandFailedException,
1011 : : ucb::CommandAbortedException,
1012 : : lang::IllegalArgumentException,
1013 : : uno::RuntimeException)
1014 : : {
1015 : : try
1016 : : {
1017 [ # # ]: 0 : if (!extension.is())
1018 : 0 : return 0;
1019 [ # # ]: 0 : ::osl::MutexGuard guard(getMutex());
1020 : 0 : sal_Int32 ret = 0;
1021 : : Reference<deploy::XPackageManager> mgr =
1022 [ # # ][ # # ]: 0 : getPackageManager(extension->getRepositoryName());
[ # # ]
1023 [ # # ][ # # ]: 0 : ret = mgr->checkPrerequisites(extension, xAbortChannel, xCmdEnv);
1024 [ # # ]: 0 : if (ret)
1025 : : {
1026 : : //There are some unfulfilled prerequisites, try to revoke
1027 [ # # ][ # # ]: 0 : extension->revokePackage(false, xAbortChannel, xCmdEnv);
1028 : : }
1029 [ # # ]: 0 : const OUString id(dp_misc::getIdentifier(extension));
1030 [ # # ]: 0 : activateExtension(id, extension->getName(),
1031 [ # # ][ # # ]: 0 : isUserDisabled(id, extension->getName()), false,
[ # # ]
1032 [ # # ][ # # ]: 0 : xAbortChannel, xCmdEnv);
1033 [ # # ]: 0 : return ret;
1034 : : }
1035 : 0 : catch ( const deploy::DeploymentException& ) {
1036 : 0 : throw;
1037 : 0 : } catch ( const ucb::CommandFailedException & ) {
1038 : 0 : throw;
1039 : 0 : } catch ( const ucb::CommandAbortedException & ) {
1040 : 0 : throw;
1041 : 0 : } catch (const lang::IllegalArgumentException &) {
1042 : 0 : throw;
1043 : 0 : } catch (const uno::RuntimeException &) {
1044 : 0 : throw;
1045 [ # # # # : 0 : } catch (...) {
# # ]
1046 [ # # ]: 0 : uno::Any excOccurred = ::cppu::getCaughtException();
1047 : : deploy::DeploymentException exc(
1048 : : OUSTR("Extension Manager: exception during disableExtension"),
1049 [ # # # # : 0 : static_cast<OWeakObject*>(this), excOccurred);
# # ]
1050 [ # # ]: 0 : throw exc;
1051 : : }
1052 : : }
1053 : :
1054 : 0 : void ExtensionManager::disableExtension(
1055 : : Reference<deploy::XPackage> const & extension,
1056 : : Reference<task::XAbortChannel> const & xAbortChannel,
1057 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1058 : : throw (deploy::DeploymentException,
1059 : : ucb::CommandFailedException,
1060 : : ucb::CommandAbortedException,
1061 : : lang::IllegalArgumentException,
1062 : : uno::RuntimeException)
1063 : : {
1064 [ # # ]: 0 : ::osl::MutexGuard guard(getMutex());
1065 : 0 : uno::Any excOccurred;
1066 : 0 : bool bUserDisabled = false;
1067 : : try
1068 : : {
1069 [ # # ]: 0 : if (!extension.is())
1070 : 0 : return;
1071 [ # # ][ # # ]: 0 : const OUString repository( extension->getRepositoryName());
1072 [ # # ][ # # ]: 0 : if (!repository.equals(OUSTR("user")))
1073 : : throw lang::IllegalArgumentException(
1074 : : OUSTR("No valid repository name provided."),
1075 [ # # ][ # # ]: 0 : static_cast<cppu::OWeakObject*>(this), 0);
[ # # ]
1076 : :
1077 [ # # ]: 0 : const OUString id(dp_misc::getIdentifier(extension));
1078 [ # # ][ # # ]: 0 : bUserDisabled = isUserDisabled(id, extension->getName());
[ # # ]
1079 : :
1080 [ # # ]: 0 : activateExtension(id, extension->getName(), true, false,
1081 [ # # ][ # # ]: 0 : xAbortChannel, xCmdEnv);
1082 : : }
1083 [ # # ]: 0 : catch ( const deploy::DeploymentException& ) {
1084 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
1085 [ # # ]: 0 : } catch ( const ucb::CommandFailedException & ) {
1086 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
1087 [ # # ]: 0 : } catch ( const ucb::CommandAbortedException & ) {
1088 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
1089 [ # # ]: 0 : } catch (const lang::IllegalArgumentException &) {
1090 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
1091 [ # # ]: 0 : } catch (const uno::RuntimeException &) {
1092 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
1093 [ # # # # : 0 : } catch (...) {
# # # # ]
1094 [ # # ]: 0 : excOccurred = ::cppu::getCaughtException();
1095 : : deploy::DeploymentException exc(
1096 : : OUSTR("Extension Manager: exception during disableExtension"),
1097 [ # # # # : 0 : static_cast<OWeakObject*>(this), excOccurred);
# # ]
1098 [ # # # # ]: 0 : excOccurred <<= exc;
1099 : : }
1100 : :
1101 [ # # ]: 0 : if (excOccurred.hasValue())
1102 : : {
1103 : : try
1104 : : {
1105 : : activateExtension(dp_misc::getIdentifier(extension),
1106 [ # # ]: 0 : extension->getName(), bUserDisabled, false,
1107 [ # # ][ # # ]: 0 : xAbortChannel, xCmdEnv);
[ # # ]
1108 : : }
1109 [ # # ]: 0 : catch (...)
1110 : : {
1111 : : }
1112 [ # # ]: 0 : ::cppu::throwException(excOccurred);
1113 [ # # ][ # # ]: 0 : }
[ # # ]
1114 : : }
1115 : :
1116 : : uno::Sequence< Reference<deploy::XPackage> >
1117 : 696 : ExtensionManager::getDeployedExtensions(
1118 : : OUString const & repository,
1119 : : Reference<task::XAbortChannel> const &xAbort,
1120 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1121 : : throw (deploy::DeploymentException,
1122 : : ucb::CommandFailedException,
1123 : : ucb::CommandAbortedException,
1124 : : lang::IllegalArgumentException,
1125 : : uno::RuntimeException)
1126 : : {
1127 [ + - ]: 1392 : return getPackageManager(repository)->getDeployedPackages(
1128 [ + - ]: 1392 : xAbort, xCmdEnv);
1129 : : }
1130 : :
1131 : : Reference<deploy::XPackage>
1132 : 0 : ExtensionManager::getDeployedExtension(
1133 : : OUString const & repository,
1134 : : OUString const & identifier,
1135 : : OUString const & filename,
1136 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1137 : : throw (deploy::DeploymentException,
1138 : : ucb::CommandFailedException,
1139 : : lang::IllegalArgumentException,
1140 : : uno::RuntimeException)
1141 : : {
1142 [ # # ]: 0 : return getPackageManager(repository)->getDeployedPackage(
1143 [ # # ]: 0 : identifier, filename, xCmdEnv);
1144 : : }
1145 : :
1146 : : uno::Sequence< uno::Sequence<Reference<deploy::XPackage> > >
1147 : 124 : ExtensionManager::getAllExtensions(
1148 : : Reference<task::XAbortChannel> const & xAbort,
1149 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1150 : : throw (deploy::DeploymentException,
1151 : : ucb::CommandFailedException,
1152 : : ucb::CommandAbortedException,
1153 : : lang::IllegalArgumentException,
1154 : : uno::RuntimeException)
1155 : : {
1156 : : try
1157 : : {
1158 [ + - ]: 124 : id2extensions mapExt;
1159 : :
1160 : : uno::Sequence<Reference<deploy::XPackage> > userExt =
1161 [ + - ][ + - ]: 124 : getUserRepository()->getDeployedPackages(xAbort, xCmdEnv);
[ + - ]
1162 [ + - ][ + - ]: 124 : addExtensionsToMap(mapExt, userExt, OUSTR("user"));
1163 : : uno::Sequence<Reference<deploy::XPackage> > sharedExt =
1164 [ + - ][ + - ]: 124 : getSharedRepository()->getDeployedPackages(xAbort, xCmdEnv);
[ + - ]
1165 [ + - ][ + - ]: 124 : addExtensionsToMap(mapExt, sharedExt, OUSTR("shared"));
1166 : : uno::Sequence<Reference<deploy::XPackage> > bundledExt =
1167 [ + - ][ + - ]: 124 : getBundledRepository()->getDeployedPackages(xAbort, xCmdEnv);
[ + - ]
1168 [ + - ][ + - ]: 124 : addExtensionsToMap(mapExt, bundledExt, OUSTR("bundled"));
1169 : :
1170 : : //copy the values of the map to a vector for sorting
1171 : : ::std::vector< ::std::vector<Reference<deploy::XPackage> > >
1172 [ + - ]: 124 : vecExtensions;
1173 [ + - ]: 124 : id2extensions::const_iterator mapIt = mapExt.begin();
1174 [ + - ][ + + ]: 1116 : for (;mapIt != mapExt.end(); ++mapIt)
1175 [ + - ][ + - ]: 992 : vecExtensions.push_back(mapIt->second);
1176 : :
1177 : : //sort the element according to the identifier
1178 [ + - ]: 124 : ::std::sort(vecExtensions.begin(), vecExtensions.end(), CompIdentifiers());
1179 : :
1180 : : ::std::vector< ::std::vector<Reference<deploy::XPackage> > >::const_iterator
1181 [ + - ]: 124 : citVecVec = vecExtensions.begin();
1182 : 124 : sal_Int32 j = 0;
1183 [ + - ]: 124 : uno::Sequence< uno::Sequence<Reference<deploy::XPackage> > > seqSeq(vecExtensions.size());
1184 [ + - ][ + + ]: 1116 : for (;citVecVec != vecExtensions.end(); ++citVecVec, j++)
1185 : : {
1186 [ + - ][ + - ]: 992 : seqSeq[j] = comphelper::containerToSequence(*citVecVec);
[ + - ][ + - ]
1187 : : }
1188 [ + - ][ + - ]: 124 : return seqSeq;
[ + - ][ + - ]
[ + - ][ + - ]
1189 : :
1190 : 0 : } catch ( const deploy::DeploymentException& ) {
1191 : 0 : throw;
1192 : 0 : } catch ( const ucb::CommandFailedException & ) {
1193 : 0 : throw;
1194 : 0 : } catch ( const ucb::CommandAbortedException & ) {
1195 : 0 : throw;
1196 : 0 : } catch (const lang::IllegalArgumentException &) {
1197 : 0 : throw;
1198 : 0 : } catch (const uno::RuntimeException &) {
1199 : 0 : throw;
1200 [ # # # # : 0 : } catch (...) {
# # ]
1201 [ # # ]: 0 : uno::Any exc = ::cppu::getCaughtException();
1202 : : throw deploy::DeploymentException(
1203 : : OUSTR("Extension Manager: exception during enableExtension"),
1204 [ # # # # : 0 : static_cast<OWeakObject*>(this), exc);
# # ]
1205 : : }
1206 : : }
1207 : :
1208 : : //only to be called from unopkg!!!
1209 : 0 : void ExtensionManager::reinstallDeployedExtensions(
1210 : : OUString const & repository,
1211 : : Reference<task::XAbortChannel> const & xAbortChannel,
1212 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1213 : : throw (deploy::DeploymentException,
1214 : : ucb::CommandFailedException, ucb::CommandAbortedException,
1215 : : lang::IllegalArgumentException, uno::RuntimeException)
1216 : : {
1217 : : try
1218 : : {
1219 : : Reference<deploy::XPackageManager>
1220 [ # # ]: 0 : xPackageManager = getPackageManager(repository);
1221 : :
1222 [ # # ]: 0 : ::osl::MutexGuard guard(getMutex());
1223 [ # # ][ # # ]: 0 : xPackageManager->reinstallDeployedPackages(xAbortChannel, xCmdEnv);
1224 : : //We must sync here, otherwise we will get exceptions when extensions
1225 : : //are removed.
1226 [ # # ]: 0 : dp_misc::syncRepositories(xCmdEnv);
1227 : : const uno::Sequence< Reference<deploy::XPackage> > extensions(
1228 [ # # ][ # # ]: 0 : xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv));
1229 : :
1230 [ # # ]: 0 : for ( sal_Int32 pos = 0; pos < extensions.getLength(); ++pos )
1231 : : {
1232 : : try
1233 : : {
1234 [ # # ]: 0 : const OUString id = dp_misc::getIdentifier(extensions[ pos ]);
1235 [ # # ][ # # ]: 0 : const OUString fileName = extensions[ pos ]->getName();
1236 : : OSL_ASSERT(!id.isEmpty());
1237 [ # # ][ # # ]: 0 : activateExtension(id, fileName, false, true, xAbortChannel, xCmdEnv );
1238 : : }
1239 [ # # ]: 0 : catch (const lang::DisposedException &)
1240 : : {
1241 : : }
1242 [ # # ][ # # ]: 0 : }
1243 : 0 : } catch ( const deploy::DeploymentException& ) {
1244 : 0 : throw;
1245 : 0 : } catch ( const ucb::CommandFailedException & ) {
1246 : 0 : throw;
1247 : 0 : } catch ( const ucb::CommandAbortedException & ) {
1248 : 0 : throw;
1249 : 0 : } catch (const lang::IllegalArgumentException &) {
1250 : 0 : throw;
1251 : 0 : } catch (const uno::RuntimeException &) {
1252 : 0 : throw;
1253 [ # # # # : 0 : } catch (...) {
# # ]
1254 [ # # ]: 0 : uno::Any exc = ::cppu::getCaughtException();
1255 : : throw deploy::DeploymentException(
1256 : : OUSTR("Extension Manager: exception during enableExtension"),
1257 [ # # # # : 0 : static_cast<OWeakObject*>(this), exc);
# # ]
1258 : : }
1259 : 0 : }
1260 : :
1261 : 62 : sal_Bool ExtensionManager::synchronize(
1262 : : Reference<task::XAbortChannel> const & xAbortChannel,
1263 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1264 : : throw (deploy::DeploymentException,
1265 : : ucb::CommandFailedException,
1266 : : ucb::CommandAbortedException,
1267 : : lang::IllegalArgumentException,
1268 : : uno::RuntimeException)
1269 : : {
1270 : : try
1271 : : {
1272 : 62 : sal_Bool bModified = sal_False;
1273 : :
1274 [ + - ]: 62 : ::osl::MutexGuard guard(getMutex());
1275 [ + - ][ + - ]: 62 : String sSynchronizingShared(StrSyncRepository::get());
1276 [ + - ][ + - ]: 62 : sSynchronizingShared.SearchAndReplaceAllAscii( "%NAME", OUSTR("shared"));
[ + - ][ + - ]
1277 [ + - ][ + - ]: 62 : dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared);
1278 [ + - ][ + - ]: 62 : bModified = getSharedRepository()->synchronize(xAbortChannel, xCmdEnv);
[ + - ]
1279 [ + - ][ + - ]: 62 : progressShared.update(OUSTR("\n\n"));
1280 : :
1281 [ + - ][ + - ]: 62 : String sSynchronizingBundled(StrSyncRepository::get());
1282 [ + - ][ + - ]: 62 : sSynchronizingBundled.SearchAndReplaceAllAscii( "%NAME", OUSTR("bundled"));
[ + - ][ + - ]
1283 [ + - ][ + - ]: 62 : dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);
1284 [ + - ][ + - ]: 62 : bModified |= getBundledRepository()->synchronize(xAbortChannel, xCmdEnv);
[ + - ]
1285 [ + - ][ + - ]: 62 : progressBundled.update(OUSTR("\n\n"));
1286 : :
1287 : : //Always determine the active extension.
1288 : : //TODO: Is this still necessary? (It used to be necessary for the
1289 : : // first-start optimization: The setup created the registration data
1290 : : // for the bundled extensions (share/prereg/bundled) which was copied to
1291 : : // the user installation when a user started OOo for the first time
1292 : : // after running setup. All bundled extensions were registered at that
1293 : : // moment. However, extensions with the same identifier could be in the
1294 : : // shared or user repository, in which case the respective bundled
1295 : : // extensions had to be revoked.)
1296 : : try
1297 : : {
1298 : : const uno::Sequence<uno::Sequence<Reference<deploy::XPackage> > >
1299 [ + - ]: 62 : seqSeqExt = getAllExtensions(xAbortChannel, xCmdEnv);
1300 [ + + ]: 558 : for (sal_Int32 i = 0; i < seqSeqExt.getLength(); i++)
1301 : : {
1302 : : uno::Sequence<Reference<deploy::XPackage> > const & seqExt =
1303 : 496 : seqSeqExt[i];
1304 [ + - ]: 496 : activateExtension(seqExt, isUserDisabled(seqExt), true,
1305 [ + - ]: 496 : xAbortChannel, xCmdEnv);
1306 [ + - ]: 62 : }
1307 : : }
1308 [ # # ]: 0 : catch (...)
1309 : : {
1310 : : //We catch the exception, so we can write the lastmodified file
1311 : : //so we will no repeat this everytime OOo starts.
1312 : : OSL_FAIL("Extensions Manager: synchronize");
1313 : : }
1314 : : OUString lastSyncBundled(RTL_CONSTASCII_USTRINGPARAM(
1315 [ + - ]: 62 : "$BUNDLED_EXTENSIONS_USER/lastsynchronized"));
1316 [ + - ]: 62 : writeLastModified(lastSyncBundled, xCmdEnv);
1317 : : OUString lastSyncShared(RTL_CONSTASCII_USTRINGPARAM(
1318 [ + - ]: 62 : "$SHARED_EXTENSIONS_USER/lastsynchronized"));
1319 [ + - ]: 62 : writeLastModified(lastSyncShared, xCmdEnv);
1320 [ + - ][ + - ]: 62 : return bModified;
[ + - ][ + - ]
[ + - ]
1321 : 0 : } catch ( const deploy::DeploymentException& ) {
1322 : 0 : throw;
1323 : 0 : } catch ( const ucb::CommandFailedException & ) {
1324 : 0 : throw;
1325 : 0 : } catch ( const ucb::CommandAbortedException & ) {
1326 : 0 : throw;
1327 : 0 : } catch (const lang::IllegalArgumentException &) {
1328 : 0 : throw;
1329 : 0 : } catch (const uno::RuntimeException &) {
1330 : 0 : throw;
1331 [ # # # # : 0 : } catch (...) {
# # ]
1332 [ # # ]: 0 : uno::Any exc = ::cppu::getCaughtException();
1333 : : throw deploy::DeploymentException(
1334 : : OUSTR("Extension Manager: exception in synchronize"),
1335 [ # # # # : 0 : static_cast<OWeakObject*>(this), exc);
# # ]
1336 : : }
1337 : : }
1338 : :
1339 : : // Notify the user when a new extension is to be installed. This is only the
1340 : : // case when one uses the system integration to install an extension (double
1341 : : // clicking on .oxt file etc.)). The function must only be called if there is no
1342 : : // extension with the same identifier already deployed. Then the checkUpdate
1343 : : // function will inform the user that the extension is about to be installed In
1344 : : // case the user cancels the installation a CommandFailed exception is
1345 : : // thrown.
1346 : 2 : void ExtensionManager::checkInstall(
1347 : : OUString const & displayName,
1348 : : Reference<ucb::XCommandEnvironment> const & cmdEnv)
1349 : : {
1350 : : uno::Any request(
1351 : : deploy::InstallException(
1352 : : OUSTR("Extension ") + displayName +
1353 : : OUSTR(" is about to be installed."),
1354 [ + - ][ + - ]: 2 : static_cast<OWeakObject *>(this), displayName));
[ + - ][ + - ]
[ + - ][ + - ]
1355 : 2 : bool approve = false, abort = false;
1356 [ - + ]: 2 : if (! dp_misc::interactContinuation(
1357 [ + - ]: 2 : request, task::XInteractionApprove::static_type(),
1358 [ + - ]: 2 : cmdEnv, &approve, &abort ))
1359 : : {
1360 : : OSL_ASSERT( !approve && !abort );
1361 : : throw deploy::DeploymentException(
1362 : : dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
1363 [ # # ][ # # ]: 0 : static_cast<OWeakObject *>(this), request );
[ # # ][ # # ]
1364 : : }
1365 [ + - ][ - + ]: 2 : if (abort || !approve)
1366 : : throw ucb::CommandFailedException(
1367 : : dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
1368 [ # # ][ # # ]: 2 : static_cast<OWeakObject *>(this), request );
[ # # ][ # # ]
1369 : 2 : }
1370 : :
1371 : : /* The function will make the user interaction in case there is an extension
1372 : : installed with the same id. This function may only be called if there is already
1373 : : an extension.
1374 : : */
1375 : 0 : void ExtensionManager::checkUpdate(
1376 : : OUString const & newVersion,
1377 : : OUString const & newDisplayName,
1378 : : Reference<deploy::XPackage> const & oldExtension,
1379 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv )
1380 : : {
1381 : : // package already deployed, interact --force:
1382 : : uno::Any request(
1383 : : (deploy::VersionException(
1384 : : dp_misc::getResourceString(
1385 : : RID_STR_PACKAGE_ALREADY_ADDED ) + newDisplayName,
1386 : : static_cast<OWeakObject *>(this), newVersion, newDisplayName,
1387 [ # # ][ # # ]: 0 : oldExtension ) ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1388 : 0 : bool replace = false, abort = false;
1389 [ # # ]: 0 : if (! dp_misc::interactContinuation(
1390 [ # # ]: 0 : request, task::XInteractionApprove::static_type(),
1391 [ # # ]: 0 : xCmdEnv, &replace, &abort )) {
1392 : : OSL_ASSERT( !replace && !abort );
1393 : : throw deploy::DeploymentException(
1394 : : dp_misc::getResourceString(
1395 : : RID_STR_ERROR_WHILE_ADDING) + newDisplayName,
1396 [ # # ][ # # ]: 0 : static_cast<OWeakObject *>(this), request );
[ # # ][ # # ]
1397 : : }
1398 [ # # ][ # # ]: 0 : if (abort || !replace)
1399 : : throw ucb::CommandFailedException(
1400 : : dp_misc::getResourceString(
1401 : : RID_STR_PACKAGE_ALREADY_ADDED) + newDisplayName,
1402 [ # # ][ # # ]: 0 : static_cast<OWeakObject *>(this), request );
[ # # ][ # # ]
1403 : 0 : }
1404 : :
1405 : 2 : Reference<deploy::XPackage> ExtensionManager::getTempExtension(
1406 : : OUString const & url,
1407 : : Reference<task::XAbortChannel> const & xAbortChannel,
1408 : : Reference<ucb::XCommandEnvironment> const & /*xCmdEnv*/)
1409 : :
1410 : : {
1411 [ + - ][ + - ]: 2 : Reference<ucb::XCommandEnvironment> tmpCmdEnvA(new TmpRepositoryCommandEnv());
[ + - ]
1412 [ + - ][ + - ]: 4 : Reference<deploy::XPackage> xTmpPackage = getTmpRepository()->addPackage(
1413 [ + - ][ + - ]: 2 : url, uno::Sequence<beans::NamedValue>(),OUString(), xAbortChannel, tmpCmdEnvA);
[ + - ]
1414 [ - + ]: 2 : if (!xTmpPackage.is())
1415 : : {
1416 : : throw deploy::DeploymentException(
1417 : : OUSTR("Extension Manager: Failed to create temporary XPackage for url: ") + url,
1418 [ # # ][ # # ]: 0 : static_cast<OWeakObject*>(this), uno::Any());
[ # # ]
1419 : :
1420 : : }
1421 : 2 : return xTmpPackage;
1422 : : }
1423 : :
1424 : : uno::Sequence<Reference<deploy::XPackage> > SAL_CALL
1425 : 0 : ExtensionManager::getExtensionsWithUnacceptedLicenses(
1426 : : OUString const & repository,
1427 : : Reference<ucb::XCommandEnvironment> const & xCmdEnv)
1428 : : throw (deploy::DeploymentException,
1429 : : uno::RuntimeException)
1430 : : {
1431 : : Reference<deploy::XPackageManager>
1432 [ # # ]: 0 : xPackageManager = getPackageManager(repository);
1433 [ # # ]: 0 : ::osl::MutexGuard guard(getMutex());
1434 [ # # ][ # # ]: 0 : return xPackageManager->getExtensionsWithUnacceptedLicenses(xCmdEnv);
[ # # ]
1435 : : }
1436 : :
1437 : 0 : sal_Bool ExtensionManager::isReadOnlyRepository(::rtl::OUString const & repository)
1438 : : throw (uno::RuntimeException)
1439 : : {
1440 [ # # ][ # # ]: 0 : return getPackageManager(repository)->isReadOnly();
1441 : : }
1442 : : //------------------------------------------------------------------------------
1443 : :
1444 : : namespace sdecl = comphelper::service_decl;
1445 : 124 : sdecl::class_<ExtensionManager> servicePIP;
1446 : 124 : extern sdecl::ServiceDecl const serviceDecl(
1447 : : servicePIP,
1448 : : // a private one:
1449 : : "com.sun.star.comp.deployment.ExtensionManager",
1450 : : "com.sun.star.comp.deployment.ExtensionManager");
1451 : :
1452 : : // XModifyBroadcaster
1453 : : //______________________________________________________________________________
1454 : 86 : void ExtensionManager::addModifyListener(
1455 : : Reference<util::XModifyListener> const & xListener )
1456 : : throw (uno::RuntimeException)
1457 : : {
1458 : 86 : check();
1459 : 86 : rBHelper.addListener( ::getCppuType( &xListener ), xListener );
1460 : 86 : }
1461 : :
1462 : : //______________________________________________________________________________
1463 : 46 : void ExtensionManager::removeModifyListener(
1464 : : Reference<util::XModifyListener> const & xListener )
1465 : : throw (uno::RuntimeException)
1466 : : {
1467 : 46 : check();
1468 : 0 : rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
1469 : 0 : }
1470 : :
1471 : 132 : void ExtensionManager::check()
1472 : : {
1473 [ + - ]: 132 : ::osl::MutexGuard guard( getMutex() );
1474 [ + + ][ - + ]: 132 : if (rBHelper.bInDispose || rBHelper.bDisposed) {
1475 : : throw lang::DisposedException(
1476 : : OUSTR("ExtensionManager instance has already been disposed!"),
1477 [ + - ][ + - ]: 46 : static_cast<OWeakObject *>(this) );
[ + - ]
1478 [ + - ]: 132 : }
1479 : 86 : }
1480 : :
1481 : 8 : void ExtensionManager::fireModified()
1482 : : {
1483 : : ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
1484 : 8 : util::XModifyListener::static_type() );
1485 [ + - ]: 8 : if (pContainer != 0) {
1486 : : pContainer->forEach<util::XModifyListener>(
1487 : : boost::bind(&util::XModifyListener::modified, _1,
1488 [ + - ][ + - ]: 8 : lang::EventObject(static_cast<OWeakObject *>(this))) );
[ + - ][ + - ]
[ + - ]
1489 : : }
1490 : 8 : }
1491 : :
1492 [ + - ][ + - ]: 372 : } // namespace dp_manager
1493 : :
1494 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|