LCOV - code coverage report
Current view: top level - desktop/source/deployment/manager - dp_extensionmanager.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 274 616 44.5 %
Date: 2014-11-03 Functions: 32 47 68.1 %
Legend: Lines: hit not hit

          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             : 
      21             : #include <cppuhelper/implbase1.hxx>
      22             : 
      23             : #include <comphelper/servicedecl.hxx>
      24             : #include <cppuhelper/exc_hlp.hxx>
      25             : #include <rtl/bootstrap.hxx>
      26             : #include <com/sun/star/deployment/ExtensionManager.hpp>
      27             : #include <com/sun/star/deployment/XExtensionManager.hpp>
      28             : #include <com/sun/star/deployment/thePackageManagerFactory.hpp>
      29             : #include <com/sun/star/deployment/XPackageManager.hpp>
      30             : #include <com/sun/star/deployment/XPackageManagerFactory.hpp>
      31             : #include <com/sun/star/deployment/XPackage.hpp>
      32             : #include <com/sun/star/deployment/InstallException.hpp>
      33             : #include <com/sun/star/deployment/VersionException.hpp>
      34             : #include <com/sun/star/deployment/LicenseException.hpp>
      35             : #include <com/sun/star/lang/XServiceInfo.hpp>
      36             : #include <com/sun/star/registry/XRegistryKey.hpp>
      37             : #include <com/sun/star/beans/Optional.hpp>
      38             : #include <com/sun/star/task/XInteractionApprove.hpp>
      39             : #include <com/sun/star/beans/Ambiguous.hpp>
      40             : #include <com/sun/star/uno/XComponentContext.hpp>
      41             : #include <com/sun/star/io/XInputStream.hpp>
      42             : #include <com/sun/star/util/XModifyBroadcaster.hpp>
      43             : #include <comphelper/sequence.hxx>
      44             : #include <xmlscript/xml_helper.hxx>
      45             : #include <osl/diagnose.h>
      46             : #include "dp_interact.h"
      47             : #include "dp_resource.h"
      48             : #include "dp_ucb.h"
      49             : #include "dp_identifier.hxx"
      50             : #include "dp_descriptioninfoset.hxx"
      51             : #include "dp_extensionmanager.hxx"
      52             : #include "dp_commandenvironments.hxx"
      53             : #include "dp_properties.hxx"
      54             : #include <boost/bind.hpp>
      55             : 
      56             : #include <list>
      57             : #include <boost/unordered_map.hpp>
      58             : #include <algorithm>
      59             : #include <set>
      60             : 
      61             : namespace lang  = com::sun::star::lang;
      62             : namespace registry = com::sun::star::registry;
      63             : namespace task = com::sun::star::task;
      64             : namespace ucb = com::sun::star::ucb;
      65             : namespace uno = com::sun::star::uno;
      66             : namespace beans = com::sun::star::beans;
      67             : namespace util = com::sun::star::util;
      68             : 
      69             : using ::com::sun::star::uno::Reference;
      70             : 
      71             : namespace {
      72             : 
      73             : struct CompIdentifiers
      74             : {
      75           0 :     bool operator() (::std::vector<Reference<css::deployment::XPackage> > const & a,
      76             :                      ::std::vector<Reference<css::deployment::XPackage> > const & b)
      77             :         {
      78           0 :             if (getName(a).compareTo(getName(b)) < 0)
      79           0 :                 return true;
      80           0 :             return false;
      81             :         }
      82             : 
      83             :     OUString getName(::std::vector<Reference<css::deployment::XPackage> > const & a);
      84             : };
      85             : 
      86           0 : OUString CompIdentifiers::getName(::std::vector<Reference<css::deployment::XPackage> > const & a)
      87             : {
      88             :     OSL_ASSERT(a.size() == 3);
      89             :     //get the first non-null reference
      90           0 :     Reference<css::deployment::XPackage>  extension;
      91           0 :     ::std::vector<Reference<css::deployment::XPackage> >::const_iterator it = a.begin();
      92           0 :     for (; it != a.end(); ++it)
      93             :     {
      94           0 :         if (it->is())
      95             :         {
      96           0 :             extension = *it;
      97           0 :             break;
      98             :         }
      99             :     }
     100             :     OSL_ASSERT(extension.is());
     101           0 :     return extension->getDisplayName();
     102             : }
     103             : 
     104         128 : void writeLastModified(OUString & url, Reference<ucb::XCommandEnvironment> const & xCmdEnv, Reference< uno::XComponentContext > const & xContext)
     105             : {
     106             :     //Write the lastmodified file
     107             :     try {
     108         128 :         ::rtl::Bootstrap::expandMacros(url);
     109         128 :         ::ucbhelper::Content ucbStamp(url, xCmdEnv, xContext);
     110         128 :         dp_misc::erase_path( url, xCmdEnv );
     111         256 :         OString stamp("1" );
     112             :         Reference<css::io::XInputStream> xData(
     113             :             ::xmlscript::createInputStream(
     114             :                 ::rtl::ByteSequence(
     115         128 :                     reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
     116         384 :                     stamp.getLength() ) ) );
     117         256 :         ucbStamp.writeStream( xData, true /* replace existing */ );
     118             :     }
     119           0 :     catch(...)
     120             :     {
     121           0 :         uno::Any exc(::cppu::getCaughtException());
     122           0 :         throw css::deployment::DeploymentException("Failed to update" + url, 0, exc);
     123             :     }
     124         128 : }
     125             : 
     126             : class ExtensionRemoveGuard
     127             : {
     128             :     css::uno::Reference<css::deployment::XPackage> m_extension;
     129             :     css::uno::Reference<css::deployment::XPackageManager> m_xPackageManager;
     130             : 
     131             : public:
     132           2 :     ExtensionRemoveGuard(){};
     133           2 :     ExtensionRemoveGuard(
     134             :         css::uno::Reference<css::deployment::XPackage> const & extension,
     135             :         css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager):
     136           2 :         m_extension(extension), m_xPackageManager(xPackageManager) {}
     137             :     ~ExtensionRemoveGuard();
     138             : 
     139           0 :     void set(css::uno::Reference<css::deployment::XPackage> const & extension,
     140             :              css::uno::Reference<css::deployment::XPackageManager> const & xPackageManager) {
     141           0 :         m_extension = extension;
     142           0 :         m_xPackageManager = xPackageManager;
     143           0 :     }
     144             : };
     145             : 
     146           8 : ExtensionRemoveGuard::~ExtensionRemoveGuard()
     147             : {
     148             :     try {
     149             :         OSL_ASSERT(!(m_extension.is() && !m_xPackageManager.is()));
     150           4 :         if (m_xPackageManager.is() && m_extension.is())
     151           2 :             m_xPackageManager->removePackage(
     152             :                 dp_misc::getIdentifier(m_extension), OUString(),
     153             :                 css::uno::Reference<css::task::XAbortChannel>(),
     154           2 :                 css::uno::Reference<css::ucb::XCommandEnvironment>());
     155           0 :     } catch (...) {
     156             :         OSL_ASSERT(false);
     157             :     }
     158           4 : }
     159             : 
     160             : }
     161             : 
     162             : namespace dp_manager {
     163             : 
     164             : 
     165             : 
     166             : //ToDo: bundled extension
     167         140 : ExtensionManager::ExtensionManager( Reference< uno::XComponentContext > const& xContext) :
     168         140 :     ::cppu::WeakComponentImplHelper1< css::deployment::XExtensionManager >(getMutex()),
     169         280 :     m_xContext( xContext )
     170             : {
     171         140 :     m_xPackageManagerFactory = css::deployment::thePackageManagerFactory::get(m_xContext);
     172             :     OSL_ASSERT(m_xPackageManagerFactory.is());
     173             : 
     174         140 :     m_repositoryNames.push_back("user");
     175         140 :     m_repositoryNames.push_back("shared");
     176         140 :     m_repositoryNames.push_back("bundled");
     177         140 : }
     178             : 
     179             : 
     180             : 
     181         136 : ExtensionManager::~ExtensionManager()
     182             : {
     183         136 : }
     184             : 
     185        2698 : Reference<css::deployment::XPackageManager> ExtensionManager::getUserRepository()
     186             : {
     187        2698 :     return m_xPackageManagerFactory->getPackageManager("user");
     188             : }
     189        2666 : Reference<css::deployment::XPackageManager>  ExtensionManager::getSharedRepository()
     190             : {
     191        2666 :     return m_xPackageManagerFactory->getPackageManager("shared");
     192             : }
     193        2666 : Reference<css::deployment::XPackageManager>  ExtensionManager::getBundledRepository()
     194             : {
     195        2666 :     return m_xPackageManagerFactory->getPackageManager("bundled");
     196             : }
     197         136 : Reference<css::deployment::XPackageManager>  ExtensionManager::getTmpRepository()
     198             : {
     199         136 :     return m_xPackageManagerFactory->getPackageManager("tmp");
     200             : }
     201           0 : Reference<css::deployment::XPackageManager>  ExtensionManager::getBakRepository()
     202             : {
     203           0 :     return m_xPackageManagerFactory->getPackageManager("bak");
     204             : }
     205             : 
     206           0 : Reference<task::XAbortChannel> ExtensionManager::createAbortChannel()
     207             :     throw (uno::RuntimeException, std::exception)
     208             : {
     209           0 :     return new dp_misc::AbortChannel;
     210             : }
     211             : 
     212             : css::uno::Reference<css::deployment::XPackageManager>
     213        7490 : ExtensionManager::getPackageManager(OUString const & repository)
     214             :     throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
     215             : {
     216        7490 :     Reference<css::deployment::XPackageManager> xPackageManager;
     217        7490 :     if (repository == "user")
     218        2558 :         xPackageManager = getUserRepository();
     219        4932 :     else if (repository == "shared")
     220        2466 :         xPackageManager = getSharedRepository();
     221        2466 :     else if (repository == "bundled")
     222        2466 :         xPackageManager = getBundledRepository();
     223           0 :     else if (repository == "tmp")
     224           0 :         xPackageManager = getTmpRepository();
     225           0 :     else if (repository == "bak")
     226           0 :         xPackageManager = getBakRepository();
     227             :     else
     228             :         throw lang::IllegalArgumentException(
     229             :             "No valid repository name provided.",
     230           0 :             static_cast<cppu::OWeakObject*>(this), 0);
     231        7462 :     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         384 : void ExtensionManager::addExtensionsToMap(
     242             :     id2extensions & mapExt,
     243             :     uno::Sequence<Reference<css::deployment::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         384 :         m_repositoryNames.begin();
     250         384 :     int index = 0;
     251         768 :     for (;citNames != m_repositoryNames.end(); ++citNames, ++index)
     252             :     {
     253         768 :         if (citNames->equals(repository))
     254         384 :             break;
     255             :     }
     256             : 
     257         384 :     for (int i = 0; i < seqExt.getLength(); ++i)
     258             :     {
     259           0 :         Reference<css::deployment::XPackage> const & xExtension = seqExt[i];
     260           0 :         OUString id = dp_misc::getIdentifier(xExtension);
     261           0 :         id2extensions::iterator ivec =  mapExt.find(id);
     262           0 :         if (ivec == mapExt.end())
     263             :         {
     264           0 :             ::std::vector<Reference<css::deployment::XPackage> > vec(3);
     265           0 :             vec[index] = xExtension;
     266           0 :             mapExt[id] = vec;
     267             :         }
     268             :         else
     269             :         {
     270           0 :             ivec->second[index] = xExtension;
     271             :         }
     272           0 :     }
     273         384 : }
     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<css::deployment::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<css::deployment::XPackage> > extensionList;
     294             :     Reference<css::deployment::XPackageManager> lRepos[] = {
     295          16 :           getUserRepository(), getSharedRepository(), getBundledRepository() };
     296          32 :     for (int i(0); i != SAL_N_ELEMENTS(lRepos); ++i)
     297             :     {
     298          24 :         Reference<css::deployment::XPackage> xPackage;
     299             :         try
     300             :         {
     301          52 :             xPackage = lRepos[i]->getDeployedPackage(
     302          28 :                 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          16 :     return extensionList;
     312             : }
     313             : 
     314             : uno::Sequence<Reference<css::deployment::XPackage> >
     315           0 : ExtensionManager::getExtensionsWithSameIdentifier(
     316             :         OUString const & identifier,
     317             :         OUString const & fileName,
     318             :         Reference< ucb::XCommandEnvironment> const & xCmdEnv )
     319             :         throw (
     320             :             css::deployment::DeploymentException,
     321             :             ucb::CommandFailedException,
     322             :             lang::IllegalArgumentException,
     323             :             uno::RuntimeException, std::exception)
     324             : {
     325             :     try
     326             :     {
     327             :         ::std::list<Reference<css::deployment::XPackage> > listExtensions =
     328             :             getExtensionsWithSameId(
     329           0 :                 identifier, fileName, xCmdEnv);
     330           0 :         bool bHasExtension = false;
     331             : 
     332             :         //throw an IllegalArgumentException if there is no extension at all.
     333             :         typedef  ::std::list<Reference<css::deployment::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           0 :                 "Could not find extension: " + identifier + ", " + fileName,
     339           0 :                 static_cast<cppu::OWeakObject*>(this), -1);
     340             : 
     341             :         return comphelper::containerToSequence<
     342             :             Reference<css::deployment::XPackage>,
     343             :             ::std::list<Reference<css::deployment::XPackage> >
     344           0 :             > (listExtensions);
     345             :     }
     346           0 :     catch ( const css::deployment::DeploymentException & )
     347             :     {
     348           0 :         throw;
     349             :     }
     350           0 :     catch ( const ucb::CommandFailedException & )
     351             :     {
     352           0 :         throw;
     353             :     }
     354           0 :     catch (css::uno::RuntimeException &)
     355             :     {
     356           0 :         throw;
     357             :     }
     358           0 :     catch (...)
     359             :     {
     360           0 :         uno::Any exc = ::cppu::getCaughtException();
     361             :         throw css::deployment::DeploymentException(
     362             :             "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<css::deployment::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<css::deployment::XPackage>,
     380             :                            ::std::list<Reference<css::deployment::XPackage> >
     381           4 :                            > (listExtensions));
     382             : }
     383             : 
     384           4 : bool ExtensionManager::isUserDisabled(
     385             :     uno::Sequence<Reference<css::deployment::XPackage> > const & seqExtSameId)
     386             : {
     387             :     OSL_ASSERT(seqExtSameId.getLength() == 3);
     388           4 :     Reference<css::deployment::XPackage> const & userExtension = seqExtSameId[0];
     389           4 :     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           4 :         if (reg.IsPresent &&
     398           4 :             ! reg.Value.IsAmbiguous && ! reg.Value.Value)
     399           0 :             return true;
     400             :     }
     401           4 :     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<css::deployment::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<css::deployment::XPackage>,
     436             :         ::std::list<Reference<css::deployment::XPackage> >
     437             :         > (listExtensions),
     438           4 :         bUserDisabled, bStartup, xAbortChannel, xCmdEnv);
     439             : 
     440           4 :     fireModified();
     441           4 : }
     442             : 
     443           4 : void ExtensionManager::activateExtension(
     444             :     uno::Sequence<Reference<css::deployment::XPackage> > const & seqExt,
     445             :     bool bUserDisabled,
     446             :     bool bStartup,
     447             :     Reference<task::XAbortChannel> const & xAbortChannel,
     448             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
     449             : {
     450           4 :     bool bActive = false;
     451           4 :     sal_Int32 len = seqExt.getLength();
     452          16 :     for (sal_Int32 i = 0; i < len; i++)
     453             :     {
     454          12 :         Reference<css::deployment::XPackage> const & aExt =  seqExt[i];
     455          12 :         if (aExt.is())
     456             :         {
     457             :             //get the registration value of the current iteration
     458             :             beans::Optional<beans::Ambiguous<sal_Bool> > optReg =
     459           2 :                 aExt->isRegistered(xAbortChannel, xCmdEnv);
     460             :             //If nothing can be registered then break
     461           2 :             if (!optReg.IsPresent)
     462           0 :                 break;
     463             : 
     464             :             //Check if this is a disabled user extension,
     465           2 :             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           2 :             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           2 :                 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           2 :                 aExt->registerPackage(bStartup, xAbortChannel, xCmdEnv);
     487             :             }
     488             :         }
     489             :     }
     490           4 : }
     491             : 
     492           2 : Reference<css::deployment::XPackage> ExtensionManager::backupExtension(
     493             :     OUString const & identifier, OUString const & fileName,
     494             :     Reference<css::deployment::XPackageManager> const & xPackageManager,
     495             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
     496             : {
     497           2 :     Reference<css::deployment::XPackage> xBackup;
     498             :     Reference<ucb::XCommandEnvironment> tmpCmdEnv(
     499           4 :         new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
     500           4 :     Reference<css::deployment::XPackage> xOldExtension;
     501           6 :     xOldExtension = xPackageManager->getDeployedPackage(
     502           4 :             identifier, fileName, tmpCmdEnv);
     503             : 
     504           2 :     if (xOldExtension.is())
     505             :     {
     506           8 :         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           4 :     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<css::deployment::XPackageTypeInfo> >
     524           0 : ExtensionManager::getSupportedPackageTypes()
     525             :     throw (uno::RuntimeException, std::exception)
     526             : {
     527           0 :     return getUserRepository()->getSupportedPackageTypes();
     528             : }
     529             : //Do some necessary checks and user interaction. This function does not
     530             : //acquire the extension manager mutex and that mutex must not be acquired
     531             : //when this function is called. doChecksForAddExtension does  synchronous
     532             : //user interactions which may require acquiring the solar mutex.
     533             : //Returns true if the extension can be installed.
     534           2 : bool ExtensionManager::doChecksForAddExtension(
     535             :     Reference<css::deployment::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<css::deployment::XPackage> & out_existingExtension )
     541             :     throw (css::deployment::DeploymentException,
     542             :            ucb::CommandFailedException,
     543             :            ucb::CommandAbortedException,
     544             :            lang::IllegalArgumentException,
     545             :            uno::RuntimeException)
     546             : {
     547             :     try
     548             :     {
     549           2 :         Reference<css::deployment::XPackage> xOldExtension;
     550           4 :         const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
     551           4 :         const OUString sFileName = xTmpExtension->getName();
     552           4 :         const OUString sDisplayName = xTmpExtension->getDisplayName();
     553           4 :         const OUString sVersion = xTmpExtension->getVersion();
     554             : 
     555             :         try
     556             :         {
     557           4 :             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           4 :         Reference<ucb::XCommandEnvironment> _xCmdEnv(xCmdEnv);
     592           4 :         ExtensionProperties props(OUString(), properties, Reference<ucb::XCommandEnvironment>(), m_xContext);
     593             : 
     594           4 :         dp_misc::DescriptionInfoset info(dp_misc::getDescriptionInfoset(xTmpExtension->getURL()));
     595             :         const ::boost::optional<dp_misc::SimpleLicenseAttributes> licenseAttributes =
     596           4 :             info.getSimpleLicenseAttributes();
     597             : 
     598           4 :         if (licenseAttributes && licenseAttributes->suppressIfRequired
     599           2 :             && props.isSuppressedLicense())
     600           0 :             _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;
     605             : 
     606           4 :         return bCanInstall;
     607             :     }
     608           0 :     catch ( const css::deployment::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             :         css::deployment::DeploymentException exc(
     621             :             "Extension Manager: exception in doChecksForAddExtension",
     622           0 :             static_cast<OWeakObject*>(this), excOccurred);
     623           0 :         throw exc;
     624           0 :     } catch (...) {
     625             :         throw uno::RuntimeException(
     626             :             "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<css::deployment::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 (css::deployment::DeploymentException,
     638             :                ucb::CommandFailedException,
     639             :                ucb::CommandAbortedException,
     640             :                lang::IllegalArgumentException,
     641             :                uno::RuntimeException, std::exception)
     642             : {
     643           2 :     Reference<css::deployment::XPackage> xNewExtension;
     644             :     //Determine the repository to use
     645           4 :     Reference<css::deployment::XPackageManager> xPackageManager;
     646           2 :     if (repository == "user")
     647           2 :         xPackageManager = getUserRepository();
     648           0 :     else if (repository == "shared")
     649           0 :         xPackageManager = getSharedRepository();
     650             :     else
     651             :         throw lang::IllegalArgumentException(
     652             :             "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           4 :     ::osl::MutexGuard addGuard(m_addMutex);
     657             : 
     658           4 :     Reference<css::deployment::XPackageManager> xTmpRepository(getTmpRepository());
     659             :         // make sure xTmpRepository is alive as long as xTmpExtension is; as
     660             :         // the "tmp" manager is only held weakly by m_xPackageManagerFactory, it
     661             :         // could otherwise be disposed early, which would in turn dispose
     662             :         // xTmpExtension's PackageRegistryBackend behind its back
     663             :     Reference<css::deployment::XPackage> xTmpExtension(
     664           2 :         xTmpRepository->addPackage(
     665             :             url, uno::Sequence<beans::NamedValue>(), OUString(), xAbortChannel,
     666           4 :             new TmpRepositoryCommandEnv()));
     667           2 :     if (!xTmpExtension.is()) {
     668             :         throw css::deployment::DeploymentException(
     669             :             ("Extension Manager: Failed to create temporary XPackage for url: "
     670           0 :              + url),
     671           0 :             static_cast<OWeakObject*>(this), uno::Any());
     672             :     }
     673             : 
     674             :     //Make sure the extension is removed from the tmp repository in case
     675             :     //of an exception
     676           4 :     ExtensionRemoveGuard tmpExtensionRemoveGuard(xTmpExtension, getTmpRepository());
     677           4 :     ExtensionRemoveGuard bakExtensionRemoveGuard;
     678           4 :     const OUString sIdentifier = dp_misc::getIdentifier(xTmpExtension);
     679           4 :     const OUString sFileName = xTmpExtension->getName();
     680           4 :     Reference<css::deployment::XPackage> xOldExtension;
     681           4 :     Reference<css::deployment::XPackage> xExtensionBackup;
     682             : 
     683           4 :     uno::Any excOccurred2;
     684           2 :     bool bUserDisabled = false;
     685             :     bool bCanInstall = doChecksForAddExtension(
     686             :         xPackageManager,
     687             :         properties,
     688             :         xTmpExtension,
     689             :         xAbortChannel,
     690             :         xCmdEnv,
     691           2 :         xOldExtension );
     692             : 
     693             :     {
     694             :         // In this garded section (getMutex) we must not use the argument xCmdEnv
     695             :         // because it may bring up dialogs (XInteractionHandler::handle) this
     696             :         //may potententially deadlock. See issue
     697             :         //http://qa.openoffice.org/issues/show_bug.cgi?id=114933
     698             :         //By not providing xCmdEnv the underlying APIs will throw an exception if
     699             :         //the XInteractionRequest cannot be handled
     700           2 :         ::osl::MutexGuard guard(getMutex());
     701             : 
     702           2 :         if (bCanInstall)
     703             :         {
     704             :             try
     705             :             {
     706           2 :                 bUserDisabled = isUserDisabled(sIdentifier, sFileName);
     707           2 :                 if (xOldExtension.is())
     708             :                 {
     709             :                     try
     710             :                     {
     711           0 :                         xOldExtension->revokePackage(
     712           0 :                             false, xAbortChannel, Reference<ucb::XCommandEnvironment>());
     713             :                         //save the old user extension in case the user aborts
     714           0 :                         xExtensionBackup = getBakRepository()->importExtension(
     715             :                             xOldExtension, Reference<task::XAbortChannel>(),
     716           0 :                             Reference<ucb::XCommandEnvironment>());
     717           0 :                         bakExtensionRemoveGuard.set(xExtensionBackup, getBakRepository());
     718             :                     }
     719           0 :                     catch (const lang::DisposedException &)
     720             :                     {
     721             :                         //Another thread might have removed the extension meanwhile
     722             :                     }
     723             :                 }
     724             :                 //check again dependencies but prevent user interaction,
     725             :                 //We can disregard the license, because the user must have already
     726             :                 //accepted it, when we called checkPrerequisites the first time
     727             :                 SilentCheckPrerequisitesCommandEnv * pSilentCommandEnv =
     728           2 :                     new SilentCheckPrerequisitesCommandEnv();
     729           2 :                 Reference<ucb::XCommandEnvironment> silentCommandEnv(pSilentCommandEnv);
     730             : 
     731           2 :                 sal_Int32 failedPrereq = xTmpExtension->checkPrerequisites(
     732           2 :                     xAbortChannel, silentCommandEnv, true);
     733           2 :                 if (failedPrereq == 0)
     734             :                 {
     735           6 :                     xNewExtension = xPackageManager->addPackage(
     736             :                         url, properties, OUString(), xAbortChannel,
     737           4 :                         Reference<ucb::XCommandEnvironment>());
     738             :                     //If we add a user extension and there is already one which was
     739             :                     //disabled by a user, then the newly installed one is enabled. If we
     740             :                     //add to another repository then the user extension remains
     741             :                     //disabled.
     742           2 :                     bool bUserDisabled2 = bUserDisabled;
     743           2 :                     if (repository == "user")
     744           2 :                         bUserDisabled2 = false;
     745             : 
     746             :                     // pass the two values via variables to workaround gcc-4.3.4 specific bug (bnc#655912)
     747           2 :                     OUString sNewExtensionIdentifier = dp_misc::getIdentifier(xNewExtension);
     748           4 :                     OUString sNewExtensionFileName = xNewExtension->getName();
     749             : 
     750             :                     activateExtension(
     751             :                         sNewExtensionIdentifier, sNewExtensionFileName,
     752             :                         bUserDisabled2, false, xAbortChannel,
     753           4 :                         Reference<ucb::XCommandEnvironment>());
     754             :                 }
     755             :                 else
     756             :                 {
     757           0 :                     if (pSilentCommandEnv->m_Exception.hasValue())
     758           0 :                         ::cppu::throwException(pSilentCommandEnv->m_Exception);
     759           0 :                     else if ( pSilentCommandEnv->m_UnknownException.hasValue())
     760           0 :                         ::cppu::throwException(pSilentCommandEnv->m_UnknownException);
     761             :                     else
     762             :                         throw css::deployment::DeploymentException (
     763             :                             "Extension Manager: exception during addExtension, ckeckPrerequisites failed",
     764           0 :                             static_cast<OWeakObject*>(this), uno::Any());
     765           2 :                 }
     766             :             }
     767           0 :             catch ( const css::deployment::DeploymentException& ) {
     768           0 :                 excOccurred2 = ::cppu::getCaughtException();
     769           0 :             } catch ( const ucb::CommandFailedException & ) {
     770           0 :                 excOccurred2 = ::cppu::getCaughtException();
     771           0 :             } catch ( const ucb::CommandAbortedException & ) {
     772           0 :                 excOccurred2 = ::cppu::getCaughtException();
     773           0 :             } catch (const lang::IllegalArgumentException &) {
     774           0 :                 excOccurred2 = ::cppu::getCaughtException();
     775           0 :             } catch (const uno::RuntimeException &) {
     776           0 :                 excOccurred2 = ::cppu::getCaughtException();
     777           0 :             } catch (...) {
     778           0 :                 excOccurred2 = ::cppu::getCaughtException();
     779             :                 css::deployment::DeploymentException exc(
     780             :                     "Extension Manager: exception during addExtension, url: "
     781           0 :                     + url, static_cast<OWeakObject*>(this), excOccurred2);
     782           0 :                 excOccurred2 <<= exc;
     783             :             }
     784             :         }
     785             : 
     786           2 :         if (excOccurred2.hasValue())
     787             :         {
     788             :             //It does not matter what exception is thrown. We try to
     789             :             //recover the original status.
     790             :             //If the user aborted installation then a ucb::CommandAbortedException
     791             :             //is thrown.
     792             :             //Use a private AbortChannel so the user cannot interrupt.
     793             :             try
     794             :             {
     795           0 :                 if (xExtensionBackup.is())
     796             :                 {
     797             :                     Reference<css::deployment::XPackage> xRestored =
     798           0 :                         xPackageManager->importExtension(
     799             :                             xExtensionBackup, Reference<task::XAbortChannel>(),
     800           0 :                             Reference<ucb::XCommandEnvironment>());
     801             :                 }
     802             :                 activateExtension(
     803             :                     sIdentifier, sFileName, bUserDisabled, false,
     804           0 :                     Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>());
     805             :             }
     806           0 :             catch (...)
     807             :             {
     808             :             }
     809           0 :             ::cppu::throwException(excOccurred2);
     810           2 :         }
     811             :     } // leaving the garded section (getMutex())
     812             : 
     813             :     try
     814             :     {
     815           2 :         fireModified();
     816             : 
     817           0 :     }catch ( const css::deployment::DeploymentException& ) {
     818           0 :         throw;
     819           0 :     } catch ( const ucb::CommandFailedException & ) {
     820           0 :         throw;
     821           0 :     } catch ( const ucb::CommandAbortedException & ) {
     822           0 :         throw;
     823           0 :     } catch (const lang::IllegalArgumentException &) {
     824           0 :         throw;
     825           0 :     } catch (const uno::RuntimeException &) {
     826           0 :         throw;
     827           0 :     } catch (const uno::Exception &) {
     828           0 :         uno::Any excOccurred = ::cppu::getCaughtException();
     829             :         css::deployment::DeploymentException exc(
     830             :             "Extension Manager: exception in doChecksForAddExtension",
     831           0 :             static_cast<OWeakObject*>(this), excOccurred);
     832           0 :         throw exc;
     833           0 :     } catch (...) {
     834             :         throw uno::RuntimeException(
     835             :             "Extension Manager: unexpected exception in doChecksForAddExtension",
     836           0 :             static_cast<OWeakObject*>(this));
     837             :     }
     838             : 
     839           4 :     return xNewExtension;
     840             : }
     841             : 
     842           2 : void ExtensionManager::removeExtension(
     843             :     OUString const & identifier, OUString const & fileName,
     844             :     OUString const & repository,
     845             :     Reference<task::XAbortChannel> const & xAbortChannel,
     846             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
     847             :     throw (css::deployment::DeploymentException,
     848             :            ucb::CommandFailedException,
     849             :            ucb::CommandAbortedException,
     850             :            lang::IllegalArgumentException,
     851             :            uno::RuntimeException, std::exception)
     852             : {
     853           2 :     uno::Any excOccurred1;
     854           4 :     Reference<css::deployment::XPackage> xExtensionBackup;
     855           4 :     Reference<css::deployment::XPackageManager> xPackageManager;
     856           2 :     bool bUserDisabled = false;
     857           4 :     ::osl::MutexGuard guard(getMutex());
     858             :     try
     859             :     {
     860             : //Determine the repository to use
     861           2 :         if (repository == "user")
     862           2 :             xPackageManager = getUserRepository();
     863           0 :         else if (repository == "shared")
     864           0 :             xPackageManager = getSharedRepository();
     865             :         else
     866             :             throw lang::IllegalArgumentException(
     867             :                 "No valid repository name provided.",
     868           0 :                 static_cast<cppu::OWeakObject*>(this), 0);
     869             : 
     870           2 :         bUserDisabled = isUserDisabled(identifier, fileName);
     871             :         //Backup the extension, in case the user cancels the action
     872           4 :         xExtensionBackup = backupExtension(
     873           2 :             identifier, fileName, xPackageManager, xCmdEnv);
     874             : 
     875             :         //revoke the extension if it is active
     876             :         Reference<css::deployment::XPackage> xOldExtension =
     877           2 :             xPackageManager->getDeployedPackage(
     878           2 :                 identifier, fileName, xCmdEnv);
     879           2 :         xOldExtension->revokePackage(false, xAbortChannel, xCmdEnv);
     880             : 
     881           2 :         xPackageManager->removePackage(
     882           2 :             identifier, fileName, xAbortChannel, xCmdEnv);
     883             :         activateExtension(identifier, fileName, bUserDisabled, false,
     884           2 :                           xAbortChannel, xCmdEnv);
     885           2 :         fireModified();
     886             :     }
     887           0 :     catch ( const css::deployment::DeploymentException& ) {
     888           0 :         excOccurred1 = ::cppu::getCaughtException();
     889           0 :     } catch ( const ucb::CommandFailedException & ) {
     890           0 :         excOccurred1 = ::cppu::getCaughtException();
     891           0 :     } catch ( const ucb::CommandAbortedException & ) {
     892           0 :         excOccurred1 = ::cppu::getCaughtException();
     893           0 :     } catch (const lang::IllegalArgumentException &) {
     894           0 :         excOccurred1 = ::cppu::getCaughtException();
     895           0 :     } catch (const uno::RuntimeException &) {
     896           0 :         excOccurred1 = ::cppu::getCaughtException();
     897           0 :     } catch (...) {
     898           0 :         excOccurred1 = ::cppu::getCaughtException();
     899             :         css::deployment::DeploymentException exc(
     900             :             "Extension Manager: exception during removeEtension",
     901           0 :             static_cast<OWeakObject*>(this), excOccurred1);
     902           0 :         excOccurred1 <<= exc;
     903             :     }
     904             : 
     905           2 :     if (excOccurred1.hasValue())
     906             :     {
     907             :         //User aborted installation, restore the previous situation.
     908             :         //Use a private AbortChannel so the user cannot interrupt.
     909             :         try
     910             :         {
     911             :             Reference<ucb::XCommandEnvironment> tmpCmdEnv(
     912           0 :                 new TmpRepositoryCommandEnv(xCmdEnv->getInteractionHandler()));
     913           0 :             if (xExtensionBackup.is())
     914             :             {
     915             :                 Reference<css::deployment::XPackage> xRestored =
     916           0 :                     xPackageManager->importExtension(
     917             :                         xExtensionBackup, Reference<task::XAbortChannel>(),
     918           0 :                         tmpCmdEnv);
     919             :                 activateExtension(
     920             :                     identifier, fileName, bUserDisabled, false,
     921             :                     Reference<task::XAbortChannel>(),
     922           0 :                     tmpCmdEnv);
     923             : 
     924           0 :                 getTmpRepository()->removePackage(
     925             :                     dp_misc::getIdentifier(xExtensionBackup),
     926           0 :                     xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
     927           0 :                 fireModified();
     928           0 :             }
     929             :         }
     930           0 :         catch (...)
     931             :         {
     932             :         }
     933           0 :         ::cppu::throwException(excOccurred1);
     934             :     }
     935             : 
     936           2 :     if (xExtensionBackup.is())
     937           4 :         getTmpRepository()->removePackage(
     938             :             dp_misc::getIdentifier(xExtensionBackup),
     939           4 :             xExtensionBackup->getName(), xAbortChannel, xCmdEnv);
     940           2 : }
     941             : 
     942             : // Only enable extensions from shared and user repository
     943           0 : void ExtensionManager::enableExtension(
     944             :     Reference<css::deployment::XPackage> const & extension,
     945             :     Reference<task::XAbortChannel> const & xAbortChannel,
     946             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv)
     947             :     throw (css::deployment::DeploymentException,
     948             :         ucb::CommandFailedException,
     949             :         ucb::CommandAbortedException,
     950             :         lang::IllegalArgumentException,
     951             :         uno::RuntimeException, std::exception)
     952             : {
     953           0 :     ::osl::MutexGuard guard(getMutex());
     954           0 :     bool bUserDisabled = false;
     955           0 :     uno::Any excOccurred;
     956             :     try
     957             :     {
     958           0 :         if (!extension.is())
     959           0 :             return;
     960           0 :         OUString repository = extension->getRepositoryName();
     961           0 :         if (!(repository == "user"))
     962             :             throw lang::IllegalArgumentException(
     963             :                 "No valid repository name provided.",
     964           0 :                 static_cast<cppu::OWeakObject*>(this), 0);
     965             : 
     966             :         bUserDisabled = isUserDisabled(dp_misc::getIdentifier(extension),
     967           0 :                                        extension->getName());
     968             : 
     969             :         activateExtension(dp_misc::getIdentifier(extension),
     970           0 :                           extension->getName(), false, false,
     971           0 :                           xAbortChannel, xCmdEnv);
     972             :     }
     973           0 :     catch ( const css::deployment::DeploymentException& ) {
     974           0 :         excOccurred = ::cppu::getCaughtException();
     975           0 :     } catch ( const ucb::CommandFailedException & ) {
     976           0 :         excOccurred = ::cppu::getCaughtException();
     977           0 :     } catch ( const ucb::CommandAbortedException & ) {
     978           0 :         excOccurred = ::cppu::getCaughtException();
     979           0 :     } catch (const lang::IllegalArgumentException &) {
     980           0 :         excOccurred = ::cppu::getCaughtException();
     981           0 :     } catch (const uno::RuntimeException &) {
     982           0 :         excOccurred = ::cppu::getCaughtException();
     983           0 :     } catch (...) {
     984           0 :         excOccurred = ::cppu::getCaughtException();
     985             :         css::deployment::DeploymentException exc(
     986             :             "Extension Manager: exception during enableExtension",
     987           0 :             static_cast<OWeakObject*>(this), excOccurred);
     988           0 :         excOccurred <<= exc;
     989             :     }
     990             : 
     991           0 :     if (excOccurred.hasValue())
     992             :     {
     993             :         try
     994             :         {
     995             :             activateExtension(dp_misc::getIdentifier(extension),
     996           0 :                               extension->getName(), bUserDisabled, false,
     997           0 :                               xAbortChannel, xCmdEnv);
     998             :         }
     999           0 :         catch (...)
    1000             :         {
    1001             :         }
    1002           0 :         ::cppu::throwException(excOccurred);
    1003           0 :     }
    1004             : }
    1005             : 
    1006             : /**
    1007             :  */
    1008           0 : sal_Int32 ExtensionManager::checkPrerequisitesAndEnable(
    1009             :     Reference<css::deployment::XPackage> const & extension,
    1010             :     Reference<task::XAbortChannel> const & xAbortChannel,
    1011             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv)
    1012             :     throw (css::deployment::DeploymentException,
    1013             :         ucb::CommandFailedException,
    1014             :         ucb::CommandAbortedException,
    1015             :         lang::IllegalArgumentException,
    1016             :         uno::RuntimeException, std::exception)
    1017             : {
    1018             :     try
    1019             :     {
    1020           0 :         if (!extension.is())
    1021           0 :             return 0;
    1022           0 :         ::osl::MutexGuard guard(getMutex());
    1023           0 :         sal_Int32 ret = 0;
    1024             :         Reference<css::deployment::XPackageManager> mgr =
    1025           0 :             getPackageManager(extension->getRepositoryName());
    1026           0 :         ret = mgr->checkPrerequisites(extension, xAbortChannel, xCmdEnv);
    1027           0 :         if (ret)
    1028             :         {
    1029             :             //There are some unfulfilled prerequisites, try to revoke
    1030           0 :             extension->revokePackage(false, xAbortChannel, xCmdEnv);
    1031             :         }
    1032           0 :         const OUString id(dp_misc::getIdentifier(extension));
    1033           0 :         activateExtension(id, extension->getName(),
    1034           0 :                           isUserDisabled(id, extension->getName()), false,
    1035           0 :                           xAbortChannel, xCmdEnv);
    1036           0 :         return ret;
    1037             :     }
    1038           0 :     catch ( const css::deployment::DeploymentException& ) {
    1039           0 :         throw;
    1040           0 :     } catch ( const ucb::CommandFailedException & ) {
    1041           0 :         throw;
    1042           0 :     } catch ( const ucb::CommandAbortedException & ) {
    1043           0 :         throw;
    1044           0 :     } catch (const lang::IllegalArgumentException &) {
    1045           0 :         throw;
    1046           0 :     } catch (const uno::RuntimeException &) {
    1047           0 :         throw;
    1048           0 :     } catch (...) {
    1049           0 :         uno::Any excOccurred = ::cppu::getCaughtException();
    1050             :         css::deployment::DeploymentException exc(
    1051             :             "Extension Manager: exception during disableExtension",
    1052           0 :             static_cast<OWeakObject*>(this), excOccurred);
    1053           0 :         throw exc;
    1054             :     }
    1055             : }
    1056             : 
    1057           0 : void ExtensionManager::disableExtension(
    1058             :     Reference<css::deployment::XPackage> const & extension,
    1059             :     Reference<task::XAbortChannel> const & xAbortChannel,
    1060             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
    1061             :     throw (css::deployment::DeploymentException,
    1062             :            ucb::CommandFailedException,
    1063             :            ucb::CommandAbortedException,
    1064             :            lang::IllegalArgumentException,
    1065             :            uno::RuntimeException, std::exception)
    1066             : {
    1067           0 :     ::osl::MutexGuard guard(getMutex());
    1068           0 :     uno::Any excOccurred;
    1069           0 :     bool bUserDisabled = false;
    1070             :     try
    1071             :     {
    1072           0 :         if (!extension.is())
    1073           0 :             return;
    1074           0 :         const OUString repository( extension->getRepositoryName());
    1075           0 :         if (! (repository == "user"))
    1076             :             throw lang::IllegalArgumentException(
    1077             :                 "No valid repository name provided.",
    1078           0 :                 static_cast<cppu::OWeakObject*>(this), 0);
    1079             : 
    1080           0 :         const OUString id(dp_misc::getIdentifier(extension));
    1081           0 :         bUserDisabled = isUserDisabled(id, extension->getName());
    1082             : 
    1083           0 :         activateExtension(id, extension->getName(), true, false,
    1084           0 :                           xAbortChannel, xCmdEnv);
    1085             :     }
    1086           0 :     catch ( const css::deployment::DeploymentException& ) {
    1087           0 :         excOccurred = ::cppu::getCaughtException();
    1088           0 :     } catch ( const ucb::CommandFailedException & ) {
    1089           0 :         excOccurred = ::cppu::getCaughtException();
    1090           0 :     } catch ( const ucb::CommandAbortedException & ) {
    1091           0 :         excOccurred = ::cppu::getCaughtException();
    1092           0 :     } catch (const lang::IllegalArgumentException &) {
    1093           0 :         excOccurred = ::cppu::getCaughtException();
    1094           0 :     } catch (const uno::RuntimeException &) {
    1095           0 :         excOccurred = ::cppu::getCaughtException();
    1096           0 :     } catch (...) {
    1097           0 :         excOccurred = ::cppu::getCaughtException();
    1098             :         css::deployment::DeploymentException exc(
    1099             :             "Extension Manager: exception during disableExtension",
    1100           0 :             static_cast<OWeakObject*>(this), excOccurred);
    1101           0 :         excOccurred <<= exc;
    1102             :     }
    1103             : 
    1104           0 :     if (excOccurred.hasValue())
    1105             :     {
    1106             :         try
    1107             :         {
    1108             :             activateExtension(dp_misc::getIdentifier(extension),
    1109           0 :                               extension->getName(), bUserDisabled, false,
    1110           0 :                               xAbortChannel, xCmdEnv);
    1111             :         }
    1112           0 :         catch (...)
    1113             :         {
    1114             :         }
    1115           0 :         ::cppu::throwException(excOccurred);
    1116           0 :     }
    1117             : }
    1118             : 
    1119             : uno::Sequence< Reference<css::deployment::XPackage> >
    1120        7426 :     ExtensionManager::getDeployedExtensions(
    1121             :     OUString const & repository,
    1122             :     Reference<task::XAbortChannel> const &xAbort,
    1123             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
    1124             :     throw (css::deployment::DeploymentException,
    1125             :         ucb::CommandFailedException,
    1126             :         ucb::CommandAbortedException,
    1127             :         lang::IllegalArgumentException,
    1128             :         uno::RuntimeException, std::exception)
    1129             : {
    1130       14824 :     return getPackageManager(repository)->getDeployedPackages(
    1131       14796 :         xAbort, xCmdEnv);
    1132             : }
    1133             : 
    1134             : Reference<css::deployment::XPackage>
    1135           0 :     ExtensionManager::getDeployedExtension(
    1136             :     OUString const & repository,
    1137             :     OUString const & identifier,
    1138             :     OUString const & filename,
    1139             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
    1140             :     throw (css::deployment::DeploymentException,
    1141             :         ucb::CommandFailedException,
    1142             :         lang::IllegalArgumentException,
    1143             :         uno::RuntimeException, std::exception)
    1144             : {
    1145           0 :     return getPackageManager(repository)->getDeployedPackage(
    1146           0 :         identifier, filename, xCmdEnv);
    1147             : }
    1148             : 
    1149             : uno::Sequence< uno::Sequence<Reference<css::deployment::XPackage> > >
    1150         128 :     ExtensionManager::getAllExtensions(
    1151             :     Reference<task::XAbortChannel> const & xAbort,
    1152             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
    1153             :     throw (css::deployment::DeploymentException,
    1154             :         ucb::CommandFailedException,
    1155             :         ucb::CommandAbortedException,
    1156             :         lang::IllegalArgumentException,
    1157             :         uno::RuntimeException, std::exception)
    1158             : {
    1159             :     try
    1160             :     {
    1161         128 :         id2extensions mapExt;
    1162             : 
    1163             :         uno::Sequence<Reference<css::deployment::XPackage> > userExt =
    1164         256 :             getUserRepository()->getDeployedPackages(xAbort, xCmdEnv);
    1165         128 :         addExtensionsToMap(mapExt, userExt, "user");
    1166             :         uno::Sequence<Reference<css::deployment::XPackage> > sharedExt =
    1167         256 :             getSharedRepository()->getDeployedPackages(xAbort, xCmdEnv);
    1168         128 :         addExtensionsToMap(mapExt, sharedExt, "shared");
    1169             :         uno::Sequence<Reference<css::deployment::XPackage> > bundledExt =
    1170         256 :             getBundledRepository()->getDeployedPackages(xAbort, xCmdEnv);
    1171         128 :         addExtensionsToMap(mapExt, bundledExt, "bundled");
    1172             : 
    1173             :         // Create the tmp repository to trigger its clean up (deletion
    1174             :         // of old temporary data.)
    1175         128 :         getTmpRepository();
    1176             : 
    1177             :         //copy the values of the map to a vector for sorting
    1178             :         ::std::vector< ::std::vector<Reference<css::deployment::XPackage> > >
    1179         256 :               vecExtensions;
    1180         128 :         id2extensions::const_iterator mapIt = mapExt.begin();
    1181         128 :         for (;mapIt != mapExt.end(); ++mapIt)
    1182           0 :             vecExtensions.push_back(mapIt->second);
    1183             : 
    1184             :         //sort the element according to the identifier
    1185         128 :         ::std::sort(vecExtensions.begin(), vecExtensions.end(), CompIdentifiers());
    1186             : 
    1187             :         ::std::vector< ::std::vector<Reference<css::deployment::XPackage> > >::const_iterator
    1188         128 :               citVecVec = vecExtensions.begin();
    1189         128 :         sal_Int32 j = 0;
    1190         256 :         uno::Sequence< uno::Sequence<Reference<css::deployment::XPackage> > > seqSeq(vecExtensions.size());
    1191         128 :         for (;citVecVec != vecExtensions.end(); ++citVecVec, j++)
    1192             :         {
    1193           0 :             seqSeq[j] = comphelper::containerToSequence(*citVecVec);
    1194             :         }
    1195         256 :         return seqSeq;
    1196             : 
    1197           0 :     } catch ( const css::deployment::DeploymentException& ) {
    1198           0 :         throw;
    1199           0 :     } catch ( const ucb::CommandFailedException & ) {
    1200           0 :         throw;
    1201           0 :     } catch ( const ucb::CommandAbortedException & ) {
    1202           0 :         throw;
    1203           0 :     } catch (const lang::IllegalArgumentException &) {
    1204           0 :         throw;
    1205           0 :     } catch (const uno::RuntimeException &) {
    1206           0 :         throw;
    1207           0 :     } catch (...) {
    1208           0 :         uno::Any exc = ::cppu::getCaughtException();
    1209             :         throw css::deployment::DeploymentException(
    1210             :             "Extension Manager: exception during enableExtension",
    1211           0 :             static_cast<OWeakObject*>(this), exc);
    1212             :    }
    1213             : }
    1214             : 
    1215             : // Only to be called from unopkg or soffice bootstrap (with force=true in the
    1216             : // latter case):
    1217          64 : void ExtensionManager::reinstallDeployedExtensions(
    1218             :     sal_Bool force, OUString const & repository,
    1219             :     Reference<task::XAbortChannel> const & xAbortChannel,
    1220             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
    1221             :     throw (css::deployment::DeploymentException,
    1222             :         ucb::CommandFailedException, ucb::CommandAbortedException,
    1223             :         lang::IllegalArgumentException, uno::RuntimeException, std::exception)
    1224             : {
    1225             :     try
    1226             :     {
    1227             :         Reference<css::deployment::XPackageManager>
    1228          64 :             xPackageManager = getPackageManager(repository);
    1229             : 
    1230         128 :         std::set< OUString > disabledExts;
    1231             :         {
    1232             :             const uno::Sequence< Reference<css::deployment::XPackage> > extensions(
    1233          64 :                 xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv));
    1234          64 :             for ( sal_Int32 pos = 0; pos < extensions.getLength(); ++pos )
    1235             :             {
    1236             :                 try
    1237             :                 {
    1238             :                     beans::Optional< beans::Ambiguous< sal_Bool > > registered(
    1239           0 :                         extensions[pos]->isRegistered(xAbortChannel, xCmdEnv));
    1240           0 :                     if (registered.IsPresent &&
    1241             :                         !(registered.Value.IsAmbiguous ||
    1242           0 :                           registered.Value.Value))
    1243             :                     {
    1244           0 :                         const OUString id = dp_misc::getIdentifier(extensions[ pos ]);
    1245             :                         OSL_ASSERT(!id.isEmpty());
    1246           0 :                         disabledExts.insert(id);
    1247             :                     }
    1248             :                 }
    1249           0 :                 catch (const lang::DisposedException &)
    1250             :                 {
    1251             :                 }
    1252          64 :             }
    1253             :         }
    1254             : 
    1255         128 :         ::osl::MutexGuard guard(getMutex());
    1256          64 :         xPackageManager->reinstallDeployedPackages(
    1257          64 :             force, xAbortChannel, xCmdEnv);
    1258             :         //We must sync here, otherwise we will get exceptions when extensions
    1259             :         //are removed.
    1260          64 :         dp_misc::syncRepositories(force, xCmdEnv);
    1261             :         const uno::Sequence< Reference<css::deployment::XPackage> > extensions(
    1262         128 :             xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv));
    1263             : 
    1264          64 :         for ( sal_Int32 pos = 0; pos < extensions.getLength(); ++pos )
    1265             :         {
    1266             :             try
    1267             :             {
    1268           0 :                 const OUString id =  dp_misc::getIdentifier(extensions[ pos ]);
    1269           0 :                 const OUString fileName = extensions[ pos ]->getName();
    1270             :                 OSL_ASSERT(!id.isEmpty());
    1271             :                 activateExtension(
    1272           0 :                     id, fileName, disabledExts.find(id) != disabledExts.end(),
    1273           0 :                     true, xAbortChannel, xCmdEnv );
    1274             :             }
    1275           0 :             catch (const lang::DisposedException &)
    1276             :             {
    1277             :             }
    1278          64 :         }
    1279           0 :     } catch ( const css::deployment::DeploymentException& ) {
    1280           0 :         throw;
    1281           0 :     } catch ( const ucb::CommandFailedException & ) {
    1282           0 :         throw;
    1283           0 :     } catch ( const ucb::CommandAbortedException & ) {
    1284           0 :         throw;
    1285           0 :     } catch (const lang::IllegalArgumentException &) {
    1286           0 :         throw;
    1287           0 :     } catch (const uno::RuntimeException &) {
    1288           0 :         throw;
    1289           0 :     } catch (...) {
    1290           0 :         uno::Any exc = ::cppu::getCaughtException();
    1291             :         throw css::deployment::DeploymentException(
    1292             :             "Extension Manager: exception during enableExtension",
    1293           0 :             static_cast<OWeakObject*>(this), exc);
    1294             :     }
    1295          64 : }
    1296             : 
    1297          64 : sal_Bool ExtensionManager::synchronize(
    1298             :     Reference<task::XAbortChannel> const & xAbortChannel,
    1299             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
    1300             :     throw (css::deployment::DeploymentException,
    1301             :            ucb::CommandFailedException,
    1302             :            ucb::CommandAbortedException,
    1303             :            lang::IllegalArgumentException,
    1304             :            uno::RuntimeException, std::exception)
    1305             : {
    1306             :     try
    1307             :     {
    1308          64 :         ::osl::MutexGuard guard(getMutex());
    1309         128 :         OUString sSynchronizingShared(StrSyncRepository::get());
    1310          64 :         sSynchronizingShared = sSynchronizingShared.replaceAll("%NAME", "shared");
    1311         128 :         dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared);
    1312          64 :         bool bModified = getSharedRepository()->synchronize(xAbortChannel, xCmdEnv);
    1313          64 :         progressShared.update("\n\n");
    1314             : 
    1315         128 :         OUString sSynchronizingBundled(StrSyncRepository::get());
    1316          64 :         sSynchronizingBundled = sSynchronizingBundled.replaceAll("%NAME", "bundled");
    1317         128 :         dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled);
    1318          64 :         bModified |= (bool)getBundledRepository()->synchronize(xAbortChannel, xCmdEnv);
    1319          64 :         progressBundled.update("\n\n");
    1320             : 
    1321             :         //Always determine the active extension.
    1322             :         //TODO: Is this still necessary?  (It used to be necessary for the
    1323             :         // first-start optimization:  The setup created the registration data
    1324             :         // for the bundled extensions (share/prereg/bundled) which was copied to
    1325             :         // the user installation when a user started OOo for the first time
    1326             :         // after running setup.  All bundled extensions were registered at that
    1327             :         // moment.  However, extensions with the same identifier could be in the
    1328             :         // shared or user repository, in which case the respective bundled
    1329             :         // extensions had to be revoked.)
    1330             :         try
    1331             :         {
    1332             :             const uno::Sequence<uno::Sequence<Reference<css::deployment::XPackage> > >
    1333          64 :                 seqSeqExt = getAllExtensions(xAbortChannel, xCmdEnv);
    1334          64 :             for (sal_Int32 i = 0; i < seqSeqExt.getLength(); i++)
    1335             :             {
    1336             :                 uno::Sequence<Reference<css::deployment::XPackage> > const & seqExt =
    1337           0 :                     seqSeqExt[i];
    1338           0 :                 activateExtension(seqExt, isUserDisabled(seqExt), true,
    1339           0 :                                   xAbortChannel, xCmdEnv);
    1340          64 :             }
    1341             :         }
    1342           0 :         catch (...)
    1343             :         {
    1344             :             //We catch the exception, so we can write the lastmodified file
    1345             :             //so we will no repeat this everytime OOo starts.
    1346             :             OSL_FAIL("Extensions Manager: synchronize");
    1347             :         }
    1348         128 :         OUString lastSyncBundled("$BUNDLED_EXTENSIONS_USER/lastsynchronized");
    1349          64 :         writeLastModified(lastSyncBundled, xCmdEnv, m_xContext);
    1350         128 :         OUString lastSyncShared("$SHARED_EXTENSIONS_USER/lastsynchronized");
    1351          64 :         writeLastModified(lastSyncShared, xCmdEnv, m_xContext);
    1352         128 :         return bModified;
    1353           0 :     } catch ( const css::deployment::DeploymentException& ) {
    1354           0 :         throw;
    1355           0 :     } catch ( const ucb::CommandFailedException & ) {
    1356           0 :         throw;
    1357           0 :     } catch ( const ucb::CommandAbortedException & ) {
    1358           0 :         throw;
    1359           0 :     } catch (const lang::IllegalArgumentException &) {
    1360           0 :         throw;
    1361           0 :     } catch (const uno::RuntimeException &) {
    1362           0 :         throw;
    1363           0 :     } catch (...) {
    1364           0 :         uno::Any exc = ::cppu::getCaughtException();
    1365             :         throw css::deployment::DeploymentException(
    1366             :             "Extension Manager: exception in synchronize",
    1367           0 :             static_cast<OWeakObject*>(this), exc);
    1368             :     }
    1369             : }
    1370             : 
    1371             : // Notify the user when a new extension is to be installed. This is only the
    1372             : // case when one uses the system integration to install an extension (double
    1373             : // clicking on .oxt file etc.)). The function must only be called if there is no
    1374             : // extension with the same identifier already deployed. Then the checkUpdate
    1375             : // function will inform the user that the extension is about to be installed In
    1376             : // case the user cancels the installation a CommandFailed exception is
    1377             : // thrown.
    1378           2 : void ExtensionManager::checkInstall(
    1379             :     OUString const & displayName,
    1380             :     Reference<ucb::XCommandEnvironment> const & cmdEnv)
    1381             : {
    1382             :         uno::Any request(
    1383             :             css::deployment::InstallException(
    1384           4 :                 "Extension " + displayName +
    1385             :                 " is about to be installed.",
    1386           6 :                 static_cast<OWeakObject *>(this), displayName));
    1387           2 :         bool approve = false, abort = false;
    1388           2 :         if (! dp_misc::interactContinuation(
    1389           2 :                 request, cppu::UnoType<task::XInteractionApprove>::get(),
    1390           2 :                 cmdEnv, &approve, &abort ))
    1391             :         {
    1392             :             OSL_ASSERT( !approve && !abort );
    1393             :             throw css::deployment::DeploymentException(
    1394           0 :                 dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
    1395           0 :                 static_cast<OWeakObject *>(this), request );
    1396             :         }
    1397           2 :         if (abort || !approve)
    1398             :             throw ucb::CommandFailedException(
    1399           0 :                 dp_misc::getResourceString(RID_STR_ERROR_WHILE_ADDING) + displayName,
    1400           0 :                 static_cast<OWeakObject *>(this), request );
    1401           2 : }
    1402             : 
    1403             : /* The function will make the user interaction in case there is an extension
    1404             : installed with the same id. This function may only be called if there is already
    1405             : an extension.
    1406             : */
    1407           0 : void ExtensionManager::checkUpdate(
    1408             :     OUString const & newVersion,
    1409             :     OUString const & newDisplayName,
    1410             :     Reference<css::deployment::XPackage> const & oldExtension,
    1411             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv )
    1412             : {
    1413             :     // package already deployed, interact --force:
    1414             :     uno::Any request(
    1415             :         (css::deployment::VersionException(
    1416             :             dp_misc::getResourceString(
    1417           0 :                 RID_STR_PACKAGE_ALREADY_ADDED ) + newDisplayName,
    1418             :             static_cast<OWeakObject *>(this), newVersion, newDisplayName,
    1419           0 :             oldExtension ) ) );
    1420           0 :     bool replace = false, abort = false;
    1421           0 :     if (! dp_misc::interactContinuation(
    1422           0 :             request, cppu::UnoType<task::XInteractionApprove>::get(),
    1423           0 :             xCmdEnv, &replace, &abort )) {
    1424             :         OSL_ASSERT( !replace && !abort );
    1425             :         throw css::deployment::DeploymentException(
    1426             :             dp_misc::getResourceString(
    1427           0 :                 RID_STR_ERROR_WHILE_ADDING) + newDisplayName,
    1428           0 :             static_cast<OWeakObject *>(this), request );
    1429             :     }
    1430           0 :     if (abort || !replace)
    1431             :         throw ucb::CommandFailedException(
    1432             :             dp_misc::getResourceString(
    1433           0 :                 RID_STR_PACKAGE_ALREADY_ADDED) + newDisplayName,
    1434           0 :             static_cast<OWeakObject *>(this), request );
    1435           0 : }
    1436             : 
    1437             : uno::Sequence<Reference<css::deployment::XPackage> > SAL_CALL
    1438           0 : ExtensionManager::getExtensionsWithUnacceptedLicenses(
    1439             :         OUString const & repository,
    1440             :         Reference<ucb::XCommandEnvironment> const & xCmdEnv)
    1441             :         throw (css::deployment::DeploymentException,
    1442             :                uno::RuntimeException, std::exception)
    1443             : {
    1444             :     Reference<css::deployment::XPackageManager>
    1445           0 :         xPackageManager = getPackageManager(repository);
    1446           0 :     ::osl::MutexGuard guard(getMutex());
    1447           0 :     return xPackageManager->getExtensionsWithUnacceptedLicenses(xCmdEnv);
    1448             : }
    1449             : 
    1450           0 : sal_Bool ExtensionManager::isReadOnlyRepository(OUString const & repository)
    1451             :         throw (uno::RuntimeException, std::exception)
    1452             : {
    1453           0 :     return getPackageManager(repository)->isReadOnly();
    1454             : }
    1455             : 
    1456             : 
    1457             : namespace sdecl = comphelper::service_decl;
    1458         140 : sdecl::class_<ExtensionManager> servicePIP;
    1459         140 : extern sdecl::ServiceDecl const serviceDecl(
    1460             :     servicePIP,
    1461             :     // a private one:
    1462             :     "com.sun.star.comp.deployment.ExtensionManager",
    1463             :     "com.sun.star.comp.deployment.ExtensionManager");
    1464             : 
    1465             : // XModifyBroadcaster
    1466             : 
    1467          78 : void ExtensionManager::addModifyListener(
    1468             :     Reference<util::XModifyListener> const & xListener )
    1469             :     throw (uno::RuntimeException, std::exception)
    1470             : {
    1471          78 :      check();
    1472          78 :      rBHelper.addListener( ::getCppuType( &xListener ), xListener );
    1473          78 : }
    1474             : 
    1475             : 
    1476          50 : void ExtensionManager::removeModifyListener(
    1477             :     Reference<util::XModifyListener> const & xListener )
    1478             :     throw (uno::RuntimeException, std::exception)
    1479             : {
    1480          50 :     check();
    1481           0 :     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
    1482           0 : }
    1483             : 
    1484         128 : void ExtensionManager::check()
    1485             : {
    1486         128 :     ::osl::MutexGuard guard( getMutex() );
    1487         128 :     if (rBHelper.bInDispose || rBHelper.bDisposed) {
    1488             :         throw lang::DisposedException(
    1489             :             "ExtensionManager instance has already been disposed!",
    1490          50 :             static_cast<OWeakObject *>(this) );
    1491         128 :     }
    1492          78 : }
    1493             : 
    1494           8 : void ExtensionManager::fireModified()
    1495             : {
    1496             :     ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
    1497           8 :         cppu::UnoType<util::XModifyListener>::get() );
    1498           8 :     if (pContainer != 0) {
    1499             :         pContainer->forEach<util::XModifyListener>(
    1500             :             boost::bind(&util::XModifyListener::modified, _1,
    1501           8 :                         lang::EventObject(static_cast<OWeakObject *>(this))) );
    1502             :     }
    1503           8 : }
    1504             : 
    1505         420 : } // namespace dp_manager
    1506             : 
    1507             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10