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

Generated by: LCOV version 1.10