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

Generated by: LCOV version 1.10