LCOV - code coverage report
Current view: top level - desktop/source/deployment/manager - dp_manager.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 319 730 43.7 %
Date: 2014-11-03 Functions: 33 52 63.5 %
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             : #include <config_features.h>
      21             : 
      22             : #include "dp_registry.hxx"
      23             : #include "dp_ucb.h"
      24             : #include "dp_resource.h"
      25             : #include "dp_platform.hxx"
      26             : #include "dp_manager.h"
      27             : #include "dp_identifier.hxx"
      28             : #include <rtl/ustrbuf.hxx>
      29             : #include <rtl/string.hxx>
      30             : #include <rtl/uri.hxx>
      31             : #include <rtl/bootstrap.hxx>
      32             : #include <osl/diagnose.h>
      33             : #include <osl/file.hxx>
      34             : #include <osl/security.hxx>
      35             : #include <cppuhelper/weakref.hxx>
      36             : #include <cppuhelper/exc_hlp.hxx>
      37             : #include <cppuhelper/implbase1.hxx>
      38             : #include <cppuhelper/interfacecontainer.hxx>
      39             : #include <comphelper/servicedecl.hxx>
      40             : #include <comphelper/sequence.hxx>
      41             : #include <xmlscript/xml_helper.hxx>
      42             : #include <svl/inettype.hxx>
      43             : #include <com/sun/star/lang/DisposedException.hpp>
      44             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      45             : #include <com/sun/star/beans/UnknownPropertyException.hpp>
      46             : #include <com/sun/star/util/XUpdatable.hpp>
      47             : #include <com/sun/star/sdbc/XResultSet.hpp>
      48             : #include <com/sun/star/sdbc/XRow.hpp>
      49             : #include <com/sun/star/ucb/XContentAccess.hpp>
      50             : #include <com/sun/star/ucb/NameClash.hpp>
      51             : #include <com/sun/star/deployment/VersionException.hpp>
      52             : #include <com/sun/star/deployment/InstallException.hpp>
      53             : #include <com/sun/star/deployment/Prerequisites.hpp>
      54             : #include <com/sun/star/task/XInteractionApprove.hpp>
      55             : #include <com/sun/star/ucb/UnsupportedCommandException.hpp>
      56             : #include <boost/bind.hpp>
      57             : #include <unotools/tempfile.hxx>
      58             : 
      59             : #include <vector>
      60             : #include <list>
      61             : #include "dp_descriptioninfoset.hxx"
      62             : #include "dp_commandenvironments.hxx"
      63             : #include "dp_properties.hxx"
      64             : 
      65             : using namespace ::dp_misc;
      66             : using namespace ::com::sun::star;
      67             : using namespace ::com::sun::star::uno;
      68             : using namespace ::com::sun::star::ucb;
      69             : 
      70             : namespace dp_log {
      71             : extern comphelper::service_decl::ServiceDecl const serviceDecl;
      72             : }
      73             : 
      74             : namespace dp_manager {
      75             : 
      76           0 : struct MatchTempDir
      77             : {
      78             :     OUString m_str;
      79           0 :     MatchTempDir( OUString const & str ) : m_str( str ) {}
      80           0 :     bool operator () ( ActivePackages::Entries::value_type const & v ) const {
      81           0 :         return v.second.temporaryName.equalsIgnoreAsciiCase( m_str );
      82             :     }
      83             : };
      84             : 
      85             : 
      86             : namespace {
      87           0 : OUString getExtensionFolder(OUString const &  parentFolder,
      88             :                             Reference<ucb::XCommandEnvironment> const & xCmdEnv,
      89             :                             Reference<uno::XComponentContext> const & xContext)
      90             : {
      91           0 :     ::ucbhelper::Content tempFolder( parentFolder, xCmdEnv, xContext );
      92             :     Reference<sdbc::XResultSet> xResultSet(
      93           0 :                 StrTitle::createCursor (tempFolder, ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
      94             : 
      95           0 :     OUString title;
      96           0 :     while (xResultSet->next())
      97             :     {
      98           0 :         title = Reference<sdbc::XRow>(
      99           0 :             xResultSet, UNO_QUERY_THROW )->getString(1 /* Title */ ) ;
     100           0 :         break;
     101             :     }
     102           0 :     return title;
     103             : }
     104             : }
     105             : 
     106         426 : void PackageManagerImpl::initActivationLayer(
     107             :     Reference<XCommandEnvironment> const & xCmdEnv )
     108             : {
     109         426 :     if (m_activePackages.isEmpty())
     110             :     {
     111             :         OSL_ASSERT( m_registryCache.isEmpty() );
     112             :         // documents temp activation:
     113           0 :         m_activePackagesDB.reset( new ActivePackages );
     114           0 :         ::ucbhelper::Content ucbContent;
     115           0 :         if (create_ucb_content( &ucbContent, m_context, xCmdEnv,
     116           0 :                                 false /* no throw */ ))
     117             :         {
     118             :             // scan for all entries in m_packagesDir:
     119             :             Reference<sdbc::XResultSet> xResultSet(
     120           0 :                         StrTitle::createCursor (ucbContent, ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS ) );
     121             : 
     122           0 :             while (xResultSet->next())
     123             :             {
     124           0 :                 Reference<sdbc::XRow> xRow( xResultSet, UNO_QUERY_THROW );
     125           0 :                 OUString title( xRow->getString( 1 /* Title */ ) );
     126             :                 // xxx todo: remove workaround for tdoc
     127           0 :                 if ( title == "this_is_a_dummy_stream_just_there_as_a_workaround_for_a_temporary_limitation_of_the_storage_api_implementation" )
     128           0 :                     continue;
     129           0 :                 if ( title == "META-INF" )
     130           0 :                     continue;
     131             : 
     132             :                 ::ucbhelper::Content sourceContent(
     133             :                     Reference<XContentAccess>(
     134           0 :                         xResultSet, UNO_QUERY_THROW )->queryContent(),
     135           0 :                     xCmdEnv, m_xComponentContext );
     136             : 
     137             :                 OUString mediaType( detectMediaType( sourceContent,
     138           0 :                                                      false /* no throw */) );
     139           0 :                 if (!mediaType.isEmpty())
     140             :                 {
     141           0 :                     ActivePackages::Data dbData;
     142             :                     insertToActivationLayer(
     143             :                         Sequence<css::beans::NamedValue>(),mediaType, sourceContent,
     144           0 :                         title, &dbData );
     145             : 
     146           0 :                     insertToActivationLayerDB( title, dbData );
     147             :                         //TODO #i73136#: insertToActivationLayerDB needs id not
     148             :                         // title, but the whole m_activePackages.getLength()==0
     149             :                         // case (i.e., document-relative deployment) currently
     150             :                         // does not work, anyway.
     151             :                 }
     152           0 :             }
     153           0 :         }
     154             :     }
     155             :     else
     156             :     {
     157             :         // user|share:
     158             :         OSL_ASSERT( !m_activePackages.isEmpty() );
     159         426 :         m_activePackages_expanded = expandUnoRcUrl( m_activePackages );
     160         426 :         m_registrationData_expanded = expandUnoRcUrl(m_registrationData);
     161         426 :         if (!m_readOnly)
     162         242 :             create_folder( 0, m_activePackages_expanded, xCmdEnv, true);
     163             : 
     164         426 :         OUString dbName;
     165         426 :         if (m_context == "user")
     166         120 :             dbName = m_activePackages_expanded + ".pmap";
     167             :         else
     168             :         {
     169             :             // Create the extension data base in the user installation
     170         306 :             create_folder( 0, m_registrationData_expanded, xCmdEnv, true);
     171         306 :             dbName = m_registrationData_expanded + "/extensions.pmap";
     172             :         }
     173             :         // The data base can always be written because it it always in the user installation
     174         426 :         m_activePackagesDB.reset( new ActivePackages( dbName, false ) );
     175             : 
     176         426 :         if (! m_readOnly && ! (m_context == "bundled"))
     177             :         {
     178             :             // clean up activation layer, scan for zombie temp dirs:
     179         242 :             ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
     180             : 
     181         484 :             ::ucbhelper::Content tempFolder( m_activePackages_expanded, xCmdEnv, m_xComponentContext );
     182             :             Reference<sdbc::XResultSet> xResultSet(
     183             :                 StrTitle::createCursor (tempFolder,
     184         484 :                                          ::ucbhelper::INCLUDE_DOCUMENTS_ONLY ) );
     185             : 
     186             :             // get all temp directories:
     187         484 :             ::std::vector<OUString> tempEntries;
     188         484 :             ::std::vector<OUString> removedEntries;
     189         484 :             while (xResultSet->next())
     190             :             {
     191             :                 OUString title(
     192             :                     Reference<sdbc::XRow>(
     193           0 :                         xResultSet, UNO_QUERY_THROW )->getString(
     194           0 :                             1 /* Title */ ) );
     195             : 
     196           0 :                 const char extensionRemoved[] = "removed";
     197           0 :                 if (title.endsWith( extensionRemoved ))
     198             :                 {
     199             :                     //save the file name withouth the "removed" part
     200             :                     sal_Int32 index = title.lastIndexOfAsciiL(
     201           0 :                         extensionRemoved, sizeof(extensionRemoved) - 1);
     202           0 :                     OUString remFile = title.copy(0, index);
     203             :                     removedEntries.push_back(::rtl::Uri::encode(
     204             :                                                 remFile, rtl_UriCharClassPchar,
     205             :                                                 rtl_UriEncodeIgnoreEscapes,
     206           0 :                                                 RTL_TEXTENCODING_UTF8 ) );
     207             :                 }
     208             :                 else
     209             :                 {
     210             :                     tempEntries.push_back( ::rtl::Uri::encode(
     211             :                                                title, rtl_UriCharClassPchar,
     212             :                                                rtl_UriEncodeIgnoreEscapes,
     213           0 :                                                RTL_TEXTENCODING_UTF8 ) );
     214             :                 }
     215           0 :             }
     216             : 
     217         242 :             bool bShared = (m_context == "shared");
     218         242 :             for ( ::std::size_t pos = 0; pos < tempEntries.size(); ++pos )
     219             :             {
     220           0 :                 OUString const & tempEntry = tempEntries[ pos ];
     221           0 :                 const MatchTempDir match( tempEntry );
     222           0 :                 if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
     223             :                     id2temp.end())
     224             :                 {
     225             :                     const OUString url(
     226           0 :                         makeURL(m_activePackages_expanded, tempEntry ) );
     227             : 
     228             :                     //In case of shared extensions, new entries are regarded as
     229             :                     //added extensions if there is no xxx.tmpremoved file.
     230           0 :                     if (bShared)
     231             :                     {
     232           0 :                         if (::std::find(removedEntries.begin(), removedEntries.end(), tempEntry) ==
     233             :                             removedEntries.end())
     234             :                         {
     235           0 :                             continue;
     236             :                         }
     237             :                         else
     238             :                         {
     239             :                             //Make sure only the same user removes the extension, who
     240             :                             //previously unregistered it. This is avoid races if multiple instances
     241             :                             //of OOo are running which all have write access to the shared installation.
     242             :                             //For example, a user removes the extension, but keeps OOo
     243             :                             //running. Parts of the extension may still be loaded and used by OOo.
     244             :                             //Therefore the extension is only deleted the next time the extension manager is
     245             :                             //run after restarting OOo. While OOo is still running, another user starts OOo
     246             :                             //which would deleted the extension files. If the same user starts another
     247             :                             //instance of OOo then the lock file will prevent this.
     248           0 :                             OUString aUserName;
     249           0 :                             ::osl::Security aSecurity;
     250           0 :                             aSecurity.getUserName( aUserName );
     251             :                             ucbhelper::Content remFileContent(
     252           0 :                                 url + "removed", Reference<XCommandEnvironment>(), m_xComponentContext);
     253           0 :                             ::rtl::ByteSequence data = dp_misc::readFile(remFileContent);
     254           0 :                             OString osData(reinterpret_cast<const sal_Char*>(data.getConstArray()),
     255           0 :                                                   data.getLength());
     256             :                             OUString sData = OStringToOUString(
     257           0 :                                 osData, RTL_TEXTENCODING_UTF8);
     258           0 :                             if (!sData.equals(aUserName))
     259           0 :                                 continue;
     260             :                         }
     261             :                     }
     262             :                     // temp entry not needed anymore:
     263           0 :                     erase_path( url + "_",
     264             :                                 Reference<XCommandEnvironment>(),
     265           0 :                                 false /* no throw: ignore errors */ );
     266             :                     erase_path( url, Reference<XCommandEnvironment>(),
     267           0 :                                 false /* no throw: ignore errors */ );
     268             :                     //delete the xxx.tmpremoved file
     269           0 :                     erase_path(url + "removed",
     270           0 :                                Reference<XCommandEnvironment>(), false);
     271             :                 }
     272         242 :             }
     273         426 :         }
     274             :     }
     275         426 : }
     276             : 
     277             : 
     278         516 : void PackageManagerImpl::initRegistryBackends()
     279             : {
     280         516 :     if (!m_registryCache.isEmpty())
     281             :         create_folder( 0, m_registryCache,
     282         516 :                        Reference<XCommandEnvironment>(), false);
     283             :     m_xRegistry.set( ::dp_registry::create(
     284             :                          m_context, m_registryCache, false,
     285         516 :                          m_xComponentContext ) );
     286         490 : }
     287             : 
     288             : // this overcomes previous rumours that the sal API is misleading
     289             : // as to whether a directory is truly read-only or not
     290         334 : static bool isMacroURLReadOnly( const OUString &rMacro )
     291             : {
     292         334 :     OUString aDirURL( rMacro );
     293         334 :     ::rtl::Bootstrap::expandMacros( aDirURL );
     294             : 
     295         334 :     ::osl::FileBase::RC aErr = ::osl::Directory::create( aDirURL );
     296         334 :     if ( aErr == ::osl::FileBase::E_None )
     297          64 :         return false; // it will be writeable
     298         270 :     if ( aErr != ::osl::FileBase::E_EXIST )
     299          90 :         return true; // some serious problem creating it
     300             : 
     301             :     bool bError;
     302         180 :     sal_uInt64 nWritten = 0;
     303         360 :     OUString aFileURL( aDirURL + "/stamp.sys" );
     304         360 :     ::osl::File aFile( aFileURL );
     305             : 
     306             :     bError = aFile.open( osl_File_OpenFlag_Read |
     307             :                          osl_File_OpenFlag_Write |
     308         180 :                          osl_File_OpenFlag_Create ) != ::osl::FileBase::E_None;
     309         180 :     if (!bError)
     310         180 :         bError = aFile.write( "1", 1, nWritten ) != ::osl::FileBase::E_None;
     311         180 :     if (aFile.close() != ::osl::FileBase::E_None)
     312           0 :         bError = true;
     313         180 :     if (osl::File::remove( aFileURL ) != ::osl::FileBase::E_None)
     314           0 :         bError = true;
     315             : 
     316             :     SAL_INFO(
     317             :         "desktop.deployment",
     318             :         "local url '" << rMacro << "' -> '" << aFileURL << "' "
     319             :             << (bError ? "is" : "is not") << " readonly\n");
     320         514 :     return bError;
     321             : }
     322             : 
     323             : 
     324         454 : Reference<deployment::XPackageManager> PackageManagerImpl::create(
     325             :     Reference<XComponentContext> const & xComponentContext,
     326             :     OUString const & context )
     327             : {
     328             :     PackageManagerImpl * that = new PackageManagerImpl(
     329         454 :         xComponentContext, context );
     330         454 :     Reference<deployment::XPackageManager> xPackageManager( that );
     331             : 
     332         908 :     OUString logFile, stamp;
     333         454 :     if ( context == "user" ) {
     334         148 :         that->m_activePackages = "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages";
     335         148 :         that->m_registrationData = "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE";
     336         148 :         that->m_registryCache = "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/registry";
     337         148 :         logFile = "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/log.txt";
     338             :         //We use the extension .sys for the file because on Windows Vista a sys
     339             :         //(as well as exe and dll) file
     340             :         //will not be written in the VirtualStore. For example if the process has no
     341             :         //admin right once cannot write to the %programfiles% folder. However, when
     342             :         //virtualization is used, the file will be written into the VirtualStore and
     343             :         //it appears as if one could write to %programfiles%. When we test for write
     344             :         //access to the office/shared folder for shared extensions then this typically
     345             :         //fails because a normal user typically cannot write to this folder. However,
     346             :         //using virtualization it appears that he/she can. Then a shared extension can
     347             :         //be installed but is only visible for the user (because the extension is in
     348             :         //the virtual store).
     349         148 :         stamp = "$UNO_USER_PACKAGES_CACHE";
     350             :     }
     351         306 :     else if ( context == "shared" ) {
     352         120 :         that->m_activePackages = "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages";
     353         120 :         that->m_registrationData = "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER";
     354         120 :         that->m_registryCache = "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/registry";
     355         120 :         logFile = "vnd.sun.star.expand:$SHARED_EXTENSIONS_USER/log.txt";
     356             : #if !HAVE_FEATURE_READONLY_INSTALLSET
     357             :         // The "shared" extensions are read-only when we have a
     358             :         // read-only installset.
     359         120 :         stamp = "$UNO_SHARED_PACKAGES_CACHE";
     360             : #endif
     361             :     }
     362         186 :     else if ( context == "bundled" ) {
     363         120 :         that->m_activePackages = "vnd.sun.star.expand:$BUNDLED_EXTENSIONS";
     364         120 :         that->m_registrationData = "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER";
     365         120 :         that->m_registryCache = "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/registry";
     366         120 :         logFile = "vnd.sun.star.expand:$BUNDLED_EXTENSIONS_USER/log.txt";
     367             :         //No stamp file. We assume that bundled is always readonly. It must not be
     368             :         //modified from ExtensionManager but only by the installer
     369             :     }
     370          66 :     else if ( context == "tmp" ) {
     371          66 :         that->m_activePackages = "vnd.sun.star.expand:$TMP_EXTENSIONS/extensions";
     372          66 :         that->m_registrationData = "vnd.sun.star.expand:$TMP_EXTENSIONS";
     373          66 :         that->m_registryCache = "vnd.sun.star.expand:$TMP_EXTENSIONS/registry";
     374          66 :         stamp = "$TMP_EXTENSIONS";
     375             :     }
     376           0 :     else if (context == "bak") {
     377           0 :         that->m_activePackages = "vnd.sun.star.expand:$BAK_EXTENSIONS/extensions";
     378           0 :         that->m_registrationData = "vnd.sun.star.expand:$BAK_EXTENSIONS";
     379           0 :         that->m_registryCache = "vnd.sun.star.expand:$BAK_EXTENSIONS/registry";
     380           0 :         stamp = "$BAK_EXTENSIONS";
     381             :     }
     382             : 
     383           0 :     else if (! context.match("vnd.sun.star.tdoc:/")) {
     384             :         throw lang::IllegalArgumentException(
     385           0 :             "invalid context given: " + context,
     386           0 :             Reference<XInterface>(), static_cast<sal_Int16>(-1) );
     387             :     }
     388             : 
     389         908 :     Reference<XCommandEnvironment> xCmdEnv;
     390             : 
     391             :     try {
     392             :         // There is no stamp for the bundled folder:
     393         454 :         if (!stamp.isEmpty())
     394         334 :             that->m_readOnly = isMacroURLReadOnly( stamp );
     395             : 
     396         454 :         if (!that->m_readOnly && !logFile.isEmpty())
     397             :         {
     398         178 :             const Any any_logFile(logFile);
     399             :             that->m_xLogFile.set(
     400         178 :                 that->m_xComponentContext->getServiceManager()
     401         356 :                 ->createInstanceWithArgumentsAndContext(
     402         356 :                     dp_log::serviceDecl.getSupportedServiceNames()[0],
     403             :                     Sequence<Any>( &any_logFile, 1 ),
     404         178 :                     that->m_xComponentContext ),
     405         534 :                 UNO_QUERY_THROW );
     406         176 :             xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv, that->m_xLogFile ) );
     407             :         }
     408             : 
     409         452 :         that->initRegistryBackends();
     410         426 :         that->initActivationLayer( xCmdEnv );
     411             : 
     412         852 :         return xPackageManager;
     413             : 
     414             :     }
     415           0 :     catch (const RuntimeException &) {
     416           0 :         throw;
     417             :     }
     418          56 :     catch (const Exception & e) {
     419          28 :         Any exc( ::cppu::getCaughtException() );
     420             :         throw lang::WrappedTargetRuntimeException(
     421          56 :             ("[context=\"" + context + "\"] caught unexpected "
     422         112 :              + exc.getValueType().getTypeName() + ": " + e.Message),
     423          84 :             Reference<XInterface>(), exc );
     424             :     }
     425             : }
     426             : 
     427             : 
     428         908 : PackageManagerImpl::~PackageManagerImpl()
     429             : {
     430         908 : }
     431             : 
     432             : 
     433          12 : void PackageManagerImpl::fireModified()
     434             : {
     435             :     ::cppu::OInterfaceContainerHelper * pContainer = rBHelper.getContainer(
     436          12 :         cppu::UnoType<util::XModifyListener>::get() );
     437          12 :     if (pContainer != 0) {
     438             :         pContainer->forEach<util::XModifyListener>(
     439             :             boost::bind(&util::XModifyListener::modified, _1,
     440           0 :                         lang::EventObject(static_cast<OWeakObject *>(this))) );
     441             :     }
     442          12 : }
     443             : 
     444             : 
     445         454 : void PackageManagerImpl::disposing()
     446             : {
     447             :     try {
     448             : //     // xxx todo: guarding?
     449             : //     ::osl::MutexGuard guard( getMutex() );
     450         454 :         try_dispose( m_xLogFile );
     451         454 :         m_xLogFile.clear();
     452         454 :         try_dispose( m_xRegistry );
     453         454 :         m_xRegistry.clear();
     454         454 :         m_activePackagesDB.reset(0);
     455         454 :         m_xComponentContext.clear();
     456             : 
     457         454 :         t_pm_helper::disposing();
     458             : 
     459             :     }
     460           0 :     catch (const RuntimeException &) {
     461           0 :         throw;
     462             :     }
     463           0 :     catch (const Exception &) {
     464           0 :         Any exc( ::cppu::getCaughtException() );
     465             :         throw lang::WrappedTargetRuntimeException(
     466             :             "caught unexpected exception while disposing...",
     467           0 :             static_cast<OWeakObject *>(this), exc );
     468             :     }
     469         454 : }
     470             : 
     471             : // XComponent
     472             : 
     473         454 : void PackageManagerImpl::dispose() throw (RuntimeException, std::exception)
     474             : {
     475             :     //Do not call check here. We must not throw an exception here if the object
     476             :     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
     477         454 :     WeakComponentImplHelperBase::dispose();
     478         454 : }
     479             : 
     480             : 
     481           0 : void PackageManagerImpl::addEventListener(
     482             :     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException, std::exception)
     483             : {
     484             :     //Do not call check here. We must not throw an exception here if the object
     485             :     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
     486           0 :     WeakComponentImplHelperBase::addEventListener( xListener );
     487           0 : }
     488             : 
     489             : 
     490           0 : void PackageManagerImpl::removeEventListener(
     491             :     Reference<lang::XEventListener> const & xListener ) throw (RuntimeException, std::exception)
     492             : {
     493             :     //Do not call check here. We must not throw an exception here if the object
     494             :     //is being disposed or is already disposed. See com.sun.star.lang.XComponent
     495           0 :     WeakComponentImplHelperBase::removeEventListener( xListener );
     496           0 : }
     497             : 
     498             : // XPackageManager
     499             : 
     500           0 : OUString PackageManagerImpl::getContext() throw (RuntimeException, std::exception)
     501             : {
     502           0 :     check();
     503           0 :     return m_context;
     504             : }
     505             : 
     506             : 
     507             : Sequence< Reference<deployment::XPackageTypeInfo> >
     508           0 : PackageManagerImpl::getSupportedPackageTypes() throw (RuntimeException, std::exception)
     509             : {
     510             :     OSL_ASSERT( m_xRegistry.is() );
     511           0 :     return m_xRegistry->getSupportedPackageTypes();
     512             : }
     513             : 
     514             : 
     515           0 : Reference<task::XAbortChannel> PackageManagerImpl::createAbortChannel()
     516             :     throw (RuntimeException, std::exception)
     517             : {
     518           0 :     check();
     519           0 :     return new AbortChannel;
     520             : }
     521             : 
     522             : // XModifyBroadcaster
     523             : 
     524           0 : void PackageManagerImpl::addModifyListener(
     525             :     Reference<util::XModifyListener> const & xListener )
     526             :     throw (RuntimeException, std::exception)
     527             : {
     528           0 :     check();
     529           0 :     rBHelper.addListener( ::getCppuType( &xListener ), xListener );
     530           0 : }
     531             : 
     532             : 
     533           0 : void PackageManagerImpl::removeModifyListener(
     534             :     Reference<util::XModifyListener> const & xListener )
     535             :     throw (RuntimeException, std::exception)
     536             : {
     537           0 :     check();
     538           0 :     rBHelper.removeListener( ::getCppuType( &xListener ), xListener );
     539           0 : }
     540             : 
     541             : 
     542           6 : OUString PackageManagerImpl::detectMediaType(
     543             :     ::ucbhelper::Content const & ucbContent_, bool throw_exc )
     544             : {
     545           6 :     ::ucbhelper::Content ucbContent(ucbContent_);
     546          12 :     OUString url( ucbContent.getURL() );
     547           6 :     OUString mediaType;
     548           6 :     if (url.match( "vnd.sun.star.tdoc:" ) || url.match( "vnd.sun.star.pkg:" ))
     549             :     {
     550             :         try {
     551           0 :             ucbContent.getPropertyValue( "MediaType" ) >>= mediaType;
     552             :         }
     553           0 :         catch (const beans::UnknownPropertyException &) {
     554             :         }
     555             :         OSL_ENSURE( !mediaType.isEmpty(), "### no media-type?!" );
     556             :     }
     557           6 :     if (mediaType.isEmpty())
     558             :     {
     559             :         try {
     560             :             Reference<deployment::XPackage> xPackage(
     561           6 :                 m_xRegistry->bindPackage(
     562           6 :                     url, OUString(), false, OUString(), ucbContent.getCommandEnvironment() ) );
     563             :             const Reference<deployment::XPackageTypeInfo> xPackageType(
     564          12 :                 xPackage->getPackageType() );
     565             :             OSL_ASSERT( xPackageType.is() );
     566           6 :             if (xPackageType.is())
     567          12 :                 mediaType = xPackageType->getMediaType();
     568             :         }
     569           0 :         catch (const lang::IllegalArgumentException & exc) {
     570           0 :             if (throw_exc)
     571           0 :                 throw;
     572             :             (void) exc;
     573             :             OSL_FAIL( OUStringToOString(
     574             :                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
     575             :         }
     576             :     }
     577          12 :     return mediaType;
     578             : }
     579             : 
     580             : 
     581           6 : OUString PackageManagerImpl::insertToActivationLayer(
     582             :     Sequence<beans::NamedValue> const & properties,
     583             :     OUString const & mediaType, ::ucbhelper::Content const & sourceContent_,
     584             :     OUString const & title, ActivePackages::Data * dbData )
     585             : {
     586           6 :     ::ucbhelper::Content sourceContent(sourceContent_);
     587             :     Reference<XCommandEnvironment> xCmdEnv(
     588          12 :         sourceContent.getCommandEnvironment() );
     589             : 
     590          12 :     OUString baseDir(m_activePackages_expanded);
     591          12 :     ::utl::TempFile aTemp(&baseDir, false);
     592          12 :     OUString tempEntry = aTemp.GetURL();
     593           6 :     tempEntry = tempEntry.copy(tempEntry.lastIndexOf('/') + 1);
     594           6 :     OUString destFolder = makeURL( m_activePackages, tempEntry);
     595           6 :     destFolder += "_";
     596             : 
     597             :     // prepare activation folder:
     598          12 :     ::ucbhelper::Content destFolderContent;
     599           6 :     create_folder( &destFolderContent, destFolder, xCmdEnv );
     600             : 
     601             :     // copy content into activation temp dir:
     602           6 :     if (mediaType.matchIgnoreAsciiCase("application/vnd.sun.star.package-bundle") ||
     603             :         // xxx todo: more sophisticated parsing
     604           0 :         mediaType.matchIgnoreAsciiCase("application/vnd.sun.star.legacy-package-bundle"))
     605             :     {
     606             :         // inflate content:
     607           6 :         OUStringBuffer buf;
     608           6 :         if (!sourceContent.isFolder())
     609             :         {
     610           4 :             buf.appendAscii( "vnd.sun.star.zip://" );
     611           4 :             buf.append( ::rtl::Uri::encode( sourceContent.getURL(),
     612             :                                             rtl_UriCharClassRegName,
     613             :                                             rtl_UriEncodeIgnoreEscapes,
     614           4 :                                             RTL_TEXTENCODING_UTF8 ) );
     615             :         }
     616             :         else
     617             :         {
     618             :             //Folder. No need to unzip, just copy
     619           2 :             buf.append(sourceContent.getURL());
     620             :         }
     621           6 :         buf.append( '/' );
     622          12 :         sourceContent = ::ucbhelper::Content(
     623          12 :             buf.makeStringAndClear(), xCmdEnv, m_xComponentContext );
     624             :     }
     625          12 :     if (! destFolderContent.transferContent(
     626             :             sourceContent, ::ucbhelper::InsertOperation_COPY,
     627          12 :             title, NameClash::OVERWRITE ))
     628           0 :         throw RuntimeException( "UCB transferContent() failed!", 0 );
     629             : 
     630             : 
     631             :     // write to DB:
     632             :     //bundled extensions should only be added by the synchronizeAddedExtensions
     633             :     //functions. Moreover, there is no "temporary folder" for bundled extensions.
     634             :     OSL_ASSERT(!(m_context == "bundled"));
     635          12 :     OUString sFolderUrl = makeURLAppendSysPathSegment(destFolderContent.getURL(), title);
     636             :     DescriptionInfoset info =
     637          12 :         dp_misc::getDescriptionInfoset(sFolderUrl);
     638           6 :     dbData->temporaryName = tempEntry;
     639           6 :     dbData->fileName = title;
     640           6 :     dbData->mediaType = mediaType;
     641           6 :     dbData->version = info.getVersion();
     642             : 
     643             :     //No write the properties file next to the extension
     644          12 :     ExtensionProperties props(sFolderUrl, properties, xCmdEnv, m_xComponentContext);
     645           6 :     props.write();
     646          12 :     return destFolder;
     647             : }
     648             : 
     649             : 
     650           6 : void PackageManagerImpl::insertToActivationLayerDB(
     651             :     OUString const & id, ActivePackages::Data const & dbData )
     652             : {
     653             :     //access to the database must be guarded. See removePackage
     654           6 :     const ::osl::MutexGuard guard( getMutex() );
     655           6 :     m_activePackagesDB->put( id, dbData );
     656           6 : }
     657             : 
     658             : 
     659             : /* The function returns true if there is an extension with the same id already
     660             :     installed which needs to be uninstalled, before the new extension can be installed.
     661             : */
     662           6 : bool PackageManagerImpl::isInstalled(
     663             :     Reference<deployment::XPackage> const & package)
     664             : {
     665           6 :     OUString id(dp_misc::getIdentifier(package));
     666          12 :     OUString fn(package->getName());
     667           6 :     bool bInstalled = false;
     668           6 :     if (m_activePackagesDB->has( id, fn ))
     669             :     {
     670           0 :         bInstalled = true;
     671             :     }
     672          12 :     return bInstalled;
     673             : }
     674             : 
     675             : // XPackageManager
     676             : 
     677           0 : Reference<deployment::XPackage> PackageManagerImpl::importExtension(
     678             :     Reference<deployment::XPackage> const & extension,
     679             :     Reference<task::XAbortChannel> const & xAbortChannel,
     680             :     Reference<XCommandEnvironment> const & xCmdEnv_ )
     681             :     throw (deployment::DeploymentException, CommandFailedException,
     682             :            CommandAbortedException, lang::IllegalArgumentException,
     683             :            RuntimeException, std::exception)
     684             : {
     685           0 :     return addPackage(extension->getURL(), Sequence<beans::NamedValue>(),
     686           0 :                       OUString(), xAbortChannel, xCmdEnv_);
     687             : }
     688             : 
     689             : /* The function adds an extension but does not register it!!!
     690             :     It may not do any user interaction. This is done in XExtensionManager::addExtension
     691             : */
     692           6 : Reference<deployment::XPackage> PackageManagerImpl::addPackage(
     693             :     OUString const & url,
     694             :     css::uno::Sequence<css::beans::NamedValue> const & properties,
     695             :     OUString const & mediaType_,
     696             :     Reference<task::XAbortChannel> const & xAbortChannel,
     697             :     Reference<XCommandEnvironment> const & xCmdEnv_ )
     698             :     throw (deployment::DeploymentException, CommandFailedException,
     699             :            CommandAbortedException, lang::IllegalArgumentException,
     700             :            RuntimeException, std::exception)
     701             : {
     702           6 :     check();
     703           6 :     if (m_readOnly)
     704             :     {
     705           0 :         OUString message;
     706           0 :         if (m_context == "shared")
     707           0 :             message = "You need write permissions to install a shared extension!";
     708             :         else
     709           0 :             message = "You need write permissions to install this extension!";
     710             :         throw deployment::DeploymentException(
     711           0 :             message, static_cast<OWeakObject *>(this), Any() );
     712             :     }
     713           6 :     Reference<XCommandEnvironment> xCmdEnv;
     714           6 :     if (m_xLogFile.is())
     715           2 :         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
     716             :     else
     717           4 :         xCmdEnv.set( xCmdEnv_ );
     718             : 
     719             :     try {
     720           6 :         ::ucbhelper::Content sourceContent;
     721           6 :         create_ucb_content( &sourceContent, url, xCmdEnv ); // throws exc
     722          12 :         const OUString title( StrTitle::getTitle( sourceContent ) );
     723             :         const OUString title_enc( ::rtl::Uri::encode(
     724             :                                       title, rtl_UriCharClassPchar,
     725             :                                       rtl_UriEncodeIgnoreEscapes,
     726          12 :                                       RTL_TEXTENCODING_UTF8 ) );
     727          12 :         OUString destFolder;
     728             : 
     729          12 :         OUString mediaType(mediaType_);
     730           6 :         if (mediaType.isEmpty())
     731           6 :             mediaType = detectMediaType( sourceContent );
     732             : 
     733          12 :         Reference<deployment::XPackage> xPackage;
     734             :         // copy file:
     735             :         progressUpdate(
     736           6 :             getResourceString(RID_STR_COPYING_PACKAGE) + title, xCmdEnv );
     737           6 :         if (m_activePackages.isEmpty())
     738             :         {
     739           0 :             ::ucbhelper::Content docFolderContent;
     740           0 :             create_folder( &docFolderContent, m_context, xCmdEnv );
     741             :             // copy into document, first:
     742           0 :             if (! docFolderContent.transferContent(
     743             :                     sourceContent, ::ucbhelper::InsertOperation_COPY,
     744             :                     OUString(),
     745           0 :                     NameClash::ASK /* xxx todo: ASK not needed? */))
     746           0 :                 throw RuntimeException("UCB transferContent() failed!", 0 );
     747             :             // set media-type:
     748             :             ::ucbhelper::Content docContent(
     749           0 :                 makeURL( m_context, title_enc ), xCmdEnv, m_xComponentContext );
     750             :                 //TODO #i73136#: using title instead of id can lead to
     751             :                 // clashes, but the whole m_activePackages.getLength()==0
     752             :                 // case (i.e., document-relative deployment) currently does
     753             :                 // not work, anyway.
     754           0 :             docContent.setPropertyValue("MediaType", Any(mediaType) );
     755             : 
     756             :             // xxx todo: obsolete in the future
     757             :             try {
     758           0 :                 docFolderContent.executeCommand( "flush", Any() );
     759             :             }
     760           0 :             catch (const UnsupportedCommandException &) {
     761           0 :             }
     762             :         }
     763          12 :         ActivePackages::Data dbData;
     764          12 :         destFolder = insertToActivationLayer(
     765           6 :             properties, mediaType, sourceContent, title, &dbData );
     766             : 
     767             : 
     768             :         // bind activation package:
     769             :         //Because every shared/user extension will be unpacked in a folder,
     770             :         //which was created with a unique name we will always have two different
     771             :         //XPackage objects, even if the second extension is the same.
     772             :         //Therefore bindPackage does not need a guard here.
     773          18 :         xPackage = m_xRegistry->bindPackage(
     774          12 :             makeURL( destFolder, title_enc ), mediaType, false, OUString(), xCmdEnv );
     775             : 
     776             :         OSL_ASSERT( xPackage.is() );
     777           6 :         if (xPackage.is())
     778             :         {
     779           6 :             bool install = false;
     780             :             try
     781             :             {
     782           6 :                 OUString const id = dp_misc::getIdentifier( xPackage );
     783             : 
     784          12 :                 ::osl::MutexGuard g(m_addMutex);
     785           6 :                 if (isInstalled(xPackage))
     786             :                 {
     787             :                     //Do not guard the complete function with the getMutex
     788           0 :                     removePackage(id, xPackage->getName(), xAbortChannel,
     789           0 :                                   xCmdEnv);
     790             :                 }
     791           6 :                 install = true;
     792          12 :                 insertToActivationLayerDB(id, dbData);
     793             :             }
     794           0 :             catch (...)
     795             :             {
     796           0 :                 deletePackageFromCache( xPackage, destFolder );
     797           0 :                 throw;
     798             :             }
     799           6 :             if (!install)
     800             :             {
     801           0 :                 deletePackageFromCache( xPackage, destFolder );
     802             :             }
     803             :             //ToDo: We should notify only if the extension is registered
     804           6 :             fireModified();
     805             :         }
     806          18 :         return xPackage;
     807             :     }
     808           0 :     catch (const RuntimeException &) {
     809           0 :         throw;
     810             :     }
     811           0 :     catch (const CommandFailedException & exc) {
     812           0 :         logIntern( Any(exc) );
     813           0 :         throw;
     814             :     }
     815           0 :     catch (const CommandAbortedException & exc) {
     816           0 :         logIntern( Any(exc) );
     817           0 :         throw;
     818             :     }
     819           0 :     catch (const deployment::DeploymentException & exc) {
     820           0 :         logIntern( Any(exc) );
     821           0 :         throw;
     822             :     }
     823           0 :     catch (const Exception &) {
     824           0 :         Any exc( ::cppu::getCaughtException() );
     825           0 :         logIntern( exc );
     826             :         throw deployment::DeploymentException(
     827           0 :             getResourceString(RID_STR_ERROR_WHILE_ADDING) + url,
     828           0 :             static_cast<OWeakObject *>(this), exc );
     829           6 :     }
     830             : }
     831           0 : void PackageManagerImpl::deletePackageFromCache(
     832             :     Reference<deployment::XPackage> const & xPackage,
     833             :     OUString const & destFolder)
     834             : {
     835           0 :     try_dispose( xPackage );
     836             : 
     837             :     //we remove the package from the uno cache
     838             :     //no service from the package may be loaded at this time!!!
     839             :     erase_path( destFolder, Reference<XCommandEnvironment>(),
     840           0 :         false /* no throw: ignore errors */ );
     841             :     //rm last character '_'
     842           0 :     OUString url = destFolder.copy(0, destFolder.getLength() - 1);
     843             :     erase_path( url, Reference<XCommandEnvironment>(),
     844           0 :         false /* no throw: ignore errors */ );
     845             : 
     846           0 : }
     847             : 
     848           6 : void PackageManagerImpl::removePackage(
     849             :     OUString const & id, OUString const & fileName,
     850             :     Reference<task::XAbortChannel> const & /*xAbortChannel*/,
     851             :     Reference<XCommandEnvironment> const & xCmdEnv_ )
     852             :     throw (deployment::DeploymentException, CommandFailedException,
     853             :            CommandAbortedException, lang::IllegalArgumentException,
     854             :            RuntimeException, std::exception)
     855             : {
     856           6 :     check();
     857             : 
     858           6 :     Reference<XCommandEnvironment> xCmdEnv;
     859           6 :     if (m_xLogFile.is())
     860           2 :         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
     861             :     else
     862           4 :         xCmdEnv.set( xCmdEnv_ );
     863             : 
     864             :     try {
     865           6 :         Reference<deployment::XPackage> xPackage;
     866             :         {
     867           6 :             const ::osl::MutexGuard guard(getMutex());
     868             :             //Check if this extension exist and throw an IllegalArgumentException
     869             :             //if it does not
     870             :             //If the files of the extension are already removed, or there is a
     871             :             //different extension at the same place, for example after updating the
     872             :             //extension, then the returned object is that which uses the database data.
     873           6 :             xPackage = getDeployedPackage_(id, fileName, xCmdEnv );
     874             : 
     875             : 
     876             :             //Because the extension is only removed the next time the extension
     877             :             //manager runs after restarting OOo, we need to indicate that a
     878             :             //shared extension was "deleted". When a user starts OOo, then it
     879             :             //will check if something changed in the shared repository. Based on
     880             :             //the flag file it will then recognize, that the extension was
     881             :             //deleted and can then update the extnesion database of the shared
     882             :             //extensions in the user installation.
     883           6 :             if ( xPackage.is() && !m_readOnly && !xPackage->isRemoved() && (m_context == "shared"))
     884             :             {
     885           0 :                 ActivePackages::Data val;
     886           0 :                 m_activePackagesDB->get( & val, id, fileName);
     887             :                 OSL_ASSERT(!val.temporaryName.isEmpty());
     888             :                 OUString url(makeURL(m_activePackages_expanded,
     889           0 :                                      val.temporaryName + "removed"));
     890           0 :                 ::ucbhelper::Content contentRemoved(url, xCmdEnv, m_xComponentContext);
     891           0 :                 OUString aUserName;
     892           0 :                 ::osl::Security aSecurity;
     893           0 :                 aSecurity.getUserName( aUserName );
     894             : 
     895           0 :                 OString stamp = OUStringToOString(aUserName, RTL_TEXTENCODING_UTF8);
     896             :                 Reference<css::io::XInputStream> xData(
     897             :                     ::xmlscript::createInputStream(
     898             :                         ::rtl::ByteSequence(
     899           0 :                             reinterpret_cast<sal_Int8 const *>(stamp.getStr()),
     900           0 :                             stamp.getLength() ) ) );
     901           0 :                 contentRemoved.writeStream( xData, true /* replace existing */ );
     902             :             }
     903           6 :             m_activePackagesDB->erase( id, fileName ); // to be removed upon next start
     904             :             //remove any cached data hold by the backend
     905           6 :             m_xRegistry->packageRemoved(xPackage->getURL(), xPackage->getPackageType()->getMediaType());
     906             :         }
     907           6 :         try_dispose( xPackage );
     908             : 
     909           6 :         fireModified();
     910             :     }
     911           0 :     catch (const RuntimeException &) {
     912           0 :         throw;
     913             :     }
     914           0 :     catch (const CommandFailedException & exc) {
     915           0 :         logIntern( Any(exc) );
     916           0 :         throw;
     917             :     }
     918           0 :     catch (const CommandAbortedException & exc) {
     919           0 :         logIntern( Any(exc) );
     920           0 :         throw;
     921             :     }
     922           0 :     catch (const deployment::DeploymentException & exc) {
     923           0 :         logIntern( Any(exc) );
     924           0 :         throw;
     925             :     }
     926           0 :     catch (const Exception &) {
     927           0 :         Any exc( ::cppu::getCaughtException() );
     928           0 :         logIntern( exc );
     929             :         throw deployment::DeploymentException(
     930           0 :             getResourceString(RID_STR_ERROR_WHILE_REMOVING) + id,
     931           0 :             static_cast<OWeakObject *>(this), exc );
     932           6 :     }
     933           6 : }
     934             : 
     935             : 
     936          14 : OUString PackageManagerImpl::getDeployPath( ActivePackages::Data const & data )
     937             : {
     938          14 :     OUStringBuffer buf;
     939          14 :     buf.append( data.temporaryName );
     940             :     //The bundled extensions are not contained in an additional folder
     941             :     //with a unique name. data.temporaryName contains already the
     942             :     //UTF8 encoded folder name. See PackageManagerImpl::synchronize
     943          14 :     if (!(m_context == "bundled"))
     944             :     {
     945          14 :         buf.appendAscii( "_/" );
     946             :         buf.append( ::rtl::Uri::encode( data.fileName, rtl_UriCharClassPchar,
     947             :                                     rtl_UriEncodeIgnoreEscapes,
     948          14 :                                     RTL_TEXTENCODING_UTF8 ) );
     949             :     }
     950          14 :     return makeURL( m_activePackages, buf.makeStringAndClear() );
     951             : }
     952             : 
     953             : 
     954          36 : Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
     955             :     OUString const & id, OUString const & fileName,
     956             :     Reference<XCommandEnvironment> const & xCmdEnv )
     957             : {
     958          36 :     ActivePackages::Data val;
     959          36 :     if (m_activePackagesDB->get( &val, id, fileName ))
     960             :     {
     961          28 :         return getDeployedPackage_( id, val, xCmdEnv, false );
     962             :     }
     963             :     throw lang::IllegalArgumentException(
     964          44 :         getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
     965          66 :         static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
     966             : }
     967             : 
     968             : 
     969          14 : Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage_(
     970             :     OUString const & id, ActivePackages::Data const & data,
     971             :     Reference<XCommandEnvironment> const & xCmdEnv, bool ignoreAlienPlatforms )
     972             : {
     973          14 :     if (ignoreAlienPlatforms)
     974             :     {
     975           0 :         OUString type, subType;
     976           0 :         INetContentTypeParameterList params;
     977           0 :         if (INetContentTypes::parse( data.mediaType, type, subType, &params ))
     978             :         {
     979             :             INetContentTypeParameter const * param = params.find(
     980           0 :                 OString("platform") );
     981           0 :             if (param != 0 && !platform_fits( param->m_sValue ))
     982             :                 throw lang::IllegalArgumentException(
     983           0 :                     getResourceString(RID_STR_NO_SUCH_PACKAGE) + id,
     984             :                     static_cast<OWeakObject *>(this),
     985           0 :                     static_cast<sal_Int16>(-1) );
     986           0 :         }
     987             :     }
     988          14 :     Reference<deployment::XPackage> xExtension;
     989             :     try
     990             :     {
     991             :         //Ignore extensions where XPackage::checkPrerequisites failed.
     992             :         //They must not be usable for this user.
     993          14 :         if (data.failedPrerequisites == "0")
     994             :         {
     995          42 :             xExtension = m_xRegistry->bindPackage(
     996          28 :                 getDeployPath( data ), data.mediaType, false, OUString(), xCmdEnv );
     997             :         }
     998             :     }
     999           0 :     catch (const deployment::InvalidRemovedParameterException& e)
    1000             :     {
    1001           0 :         xExtension = e.Extension;
    1002             :     }
    1003          14 :     return xExtension;
    1004             : }
    1005             : 
    1006             : 
    1007             : Sequence< Reference<deployment::XPackage> >
    1008        7910 : PackageManagerImpl::getDeployedPackages_(
    1009             :     Reference<XCommandEnvironment> const & xCmdEnv )
    1010             : {
    1011        7910 :     ::std::vector< Reference<deployment::XPackage> > packages;
    1012       15820 :     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
    1013        7910 :     ActivePackages::Entries::const_iterator iPos( id2temp.begin() );
    1014        7910 :     ActivePackages::Entries::const_iterator const iEnd( id2temp.end() );
    1015        7910 :     for ( ; iPos != iEnd; ++iPos )
    1016             :     {
    1017           0 :         if (! (iPos->second.failedPrerequisites == "0"))
    1018           0 :             continue;
    1019             :         try {
    1020             :             packages.push_back(
    1021             :                 getDeployedPackage_(
    1022           0 :                     iPos->first, iPos->second, xCmdEnv,
    1023             :                     true /* xxx todo: think of GUI:
    1024           0 :                             ignore other platforms than the current one */ ) );
    1025             :         }
    1026           0 :         catch (const lang::IllegalArgumentException & exc) {
    1027             :             // ignore
    1028             :             (void) exc; // avoid warnings
    1029             :             OSL_FAIL( OUStringToOString(
    1030             :                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
    1031             :         }
    1032           0 :         catch (const deployment::DeploymentException& exc) {
    1033             :             // ignore
    1034             :             (void) exc; // avoid warnings
    1035             :             OSL_FAIL( OUStringToOString(
    1036             :                             exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
    1037             :         }
    1038             :     }
    1039       15820 :     return comphelper::containerToSequence(packages);
    1040             : }
    1041             : 
    1042             : 
    1043          30 : Reference<deployment::XPackage> PackageManagerImpl::getDeployedPackage(
    1044             :     OUString const & id, OUString const & fileName,
    1045             :     Reference<XCommandEnvironment> const & xCmdEnv_ )
    1046             :     throw (deployment::DeploymentException, CommandFailedException,
    1047             :            lang::IllegalArgumentException, RuntimeException, std::exception)
    1048             : {
    1049          30 :     check();
    1050          30 :     Reference<XCommandEnvironment> xCmdEnv;
    1051          30 :     if (m_xLogFile.is())
    1052          22 :         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
    1053             :     else
    1054           8 :         xCmdEnv.set( xCmdEnv_ );
    1055             : 
    1056             :     try {
    1057          30 :         const ::osl::MutexGuard guard( getMutex() );
    1058          60 :         return getDeployedPackage_( id, fileName, xCmdEnv );
    1059             :     }
    1060          44 :     catch (const lang::IllegalArgumentException & exc) {
    1061          22 :         logIntern( Any(exc) );
    1062          22 :         throw;
    1063             :     }
    1064           0 :     catch (const RuntimeException &) {
    1065           0 :         throw;
    1066             :     }
    1067           0 :     catch (const CommandFailedException & exc) {
    1068           0 :         logIntern( Any(exc) );
    1069           0 :         throw;
    1070             :     }
    1071           0 :     catch (const deployment::DeploymentException & exc) {
    1072           0 :         logIntern( Any(exc) );
    1073           0 :         throw;
    1074             :     }
    1075           0 :     catch (const Exception &) {
    1076           0 :         Any exc( ::cppu::getCaughtException() );
    1077           0 :         logIntern( exc );
    1078             :         throw deployment::DeploymentException(
    1079             :             // ought never occur...
    1080           0 :             "error while accessing deployed package: " + id,
    1081           0 :             static_cast<OWeakObject *>(this), exc );
    1082          30 :     }
    1083             : }
    1084             : 
    1085             : 
    1086             : Sequence< Reference<deployment::XPackage> >
    1087        7910 : PackageManagerImpl::getDeployedPackages(
    1088             :     Reference<task::XAbortChannel> const &,
    1089             :     Reference<XCommandEnvironment> const & xCmdEnv_ )
    1090             :     throw (deployment::DeploymentException, CommandFailedException,
    1091             :            CommandAbortedException, lang::IllegalArgumentException,
    1092             :            RuntimeException, std::exception)
    1093             : {
    1094        7910 :     check();
    1095        7910 :     Reference<XCommandEnvironment> xCmdEnv;
    1096        7910 :     if (m_xLogFile.is())
    1097        5060 :         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
    1098             :     else
    1099        2850 :         xCmdEnv.set( xCmdEnv_ );
    1100             : 
    1101             :     try {
    1102        7910 :         const ::osl::MutexGuard guard( getMutex() );
    1103       15820 :         return getDeployedPackages_( xCmdEnv );
    1104             :     }
    1105           0 :     catch (const RuntimeException &) {
    1106           0 :         throw;
    1107             :     }
    1108           0 :     catch (const CommandFailedException & exc) {
    1109           0 :         logIntern( Any(exc) );
    1110           0 :         throw;
    1111             :     }
    1112           0 :     catch (const CommandAbortedException & exc) {
    1113           0 :         logIntern( Any(exc) );
    1114           0 :         throw;
    1115             :     }
    1116           0 :     catch (const deployment::DeploymentException & exc) {
    1117           0 :         logIntern( Any(exc) );
    1118           0 :         throw;
    1119             :     }
    1120           0 :     catch (const Exception &) {
    1121           0 :         Any exc( ::cppu::getCaughtException() );
    1122           0 :         logIntern( exc );
    1123             :         throw deployment::DeploymentException(
    1124             :             // ought never occur...
    1125           0 :             "error while getting all deployed packages: " + m_context,
    1126           0 :             static_cast<OWeakObject *>(this), exc );
    1127        7910 :     }
    1128             : }
    1129             : 
    1130             : 
    1131             : 
    1132             : 
    1133             : //ToDo: the function must not call registerPackage, do this in
    1134             : //XExtensionManager.reinstallDeployedExtensions
    1135          64 : void PackageManagerImpl::reinstallDeployedPackages(
    1136             :     sal_Bool force, Reference<task::XAbortChannel> const &  /*xAbortChannel*/,
    1137             :     Reference<XCommandEnvironment> const & xCmdEnv_ )
    1138             :     throw (deployment::DeploymentException,
    1139             :            CommandFailedException, CommandAbortedException,
    1140             :            lang::IllegalArgumentException, RuntimeException, std::exception)
    1141             : {
    1142          64 :     check();
    1143          64 :     if (!force && office_is_running())
    1144             :         throw RuntimeException(
    1145             :             "You must close any running Office process before reinstalling packages!",
    1146           0 :             static_cast<OWeakObject *>(this) );
    1147             : 
    1148          64 :     Reference<XCommandEnvironment> xCmdEnv;
    1149          64 :     if (m_xLogFile.is())
    1150           0 :         xCmdEnv.set( new CmdEnvWrapperImpl( xCmdEnv_, m_xLogFile ) );
    1151             :     else
    1152          64 :         xCmdEnv.set( xCmdEnv_ );
    1153             : 
    1154             :     try {
    1155             :         ProgressLevel progress(
    1156          64 :             xCmdEnv, "Reinstalling all deployed packages..." );
    1157             : 
    1158          64 :         try_dispose( m_xRegistry );
    1159          64 :         m_xRegistry.clear();
    1160          64 :         if (!m_registryCache.isEmpty())
    1161          64 :             erase_path( m_registryCache, xCmdEnv );
    1162          64 :         initRegistryBackends();
    1163         128 :         Reference<util::XUpdatable> xUpdatable( m_xRegistry, UNO_QUERY );
    1164          64 :         if (xUpdatable.is())
    1165         128 :             xUpdatable->update();
    1166             : 
    1167             :         //registering is done by the ExtensionManager service.
    1168             :     }
    1169           0 :     catch (const RuntimeException &) {
    1170           0 :         throw;
    1171             :     }
    1172           0 :     catch (const CommandFailedException & exc) {
    1173           0 :         logIntern( Any(exc) );
    1174           0 :         throw;
    1175             :     }
    1176           0 :     catch (const CommandAbortedException & exc) {
    1177           0 :         logIntern( Any(exc) );
    1178           0 :         throw;
    1179             :     }
    1180           0 :     catch (const deployment::DeploymentException & exc) {
    1181           0 :         logIntern( Any(exc) );
    1182           0 :         throw;
    1183             :     }
    1184           0 :     catch (const Exception &) {
    1185           0 :         Any exc( ::cppu::getCaughtException() );
    1186           0 :         logIntern( exc );
    1187             :         throw deployment::DeploymentException(
    1188           0 :             "Error while reinstalling all previously deployed packages of context " + m_context,
    1189           0 :             static_cast<OWeakObject *>(this), exc );
    1190          64 :     }
    1191          64 : }
    1192             : 
    1193             : 
    1194           0 : sal_Bool SAL_CALL PackageManagerImpl::isReadOnly(  )
    1195             :         throw (::com::sun::star::uno::RuntimeException, std::exception)
    1196             : {
    1197           0 :     return m_readOnly;
    1198             : }
    1199         128 : bool PackageManagerImpl::synchronizeRemovedExtensions(
    1200             :     Reference<task::XAbortChannel> const & xAbortChannel,
    1201             :     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
    1202             : {
    1203             : 
    1204             :     //find all which are in the extension data base but which
    1205             :     //are removed already.
    1206             :     OSL_ASSERT(!(m_context == "user"));
    1207         128 :     bool bModified = false;
    1208         128 :     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
    1209             : 
    1210             :     typedef ActivePackages::Entries::const_iterator ITActive;
    1211         128 :     bool bShared = (m_context == "shared");
    1212             : 
    1213         128 :     for (ITActive i = id2temp.begin(); i != id2temp.end(); ++i)
    1214             :     {
    1215             :         try
    1216             :         {
    1217             :             //Get the URL to the extensions folder, first make the url for the
    1218             :             //shared repository including the temporary name
    1219           0 :             OUString url = makeURL(m_activePackages, i->second.temporaryName);
    1220           0 :             if (bShared)
    1221           0 :                 url = makeURLAppendSysPathSegment( url + "_", i->second.fileName);
    1222             : 
    1223           0 :             bool bRemoved = false;
    1224             :             //Check if the URL to the extension is still the same
    1225           0 :             ::ucbhelper::Content contentExtension;
    1226             : 
    1227           0 :             if (!create_ucb_content(
    1228             :                     &contentExtension, url,
    1229           0 :                     Reference<XCommandEnvironment>(), false))
    1230             :             {
    1231           0 :                 bRemoved = true;
    1232             :             }
    1233             : 
    1234             :             //The folder is in the extension database, but it can still be deleted.
    1235             :             //look for the xxx.tmpremoved file
    1236             :             //There can also be the case that a different extension was installed
    1237             :             //in a "temp" folder with name that is already used.
    1238           0 :             if (!bRemoved && bShared)
    1239             :             {
    1240           0 :                 ::ucbhelper::Content contentRemoved;
    1241             : 
    1242           0 :                 if (create_ucb_content(
    1243             :                         &contentRemoved,
    1244           0 :                         m_activePackages_expanded + "/" +
    1245           0 :                         i->second.temporaryName + "removed",
    1246           0 :                         Reference<XCommandEnvironment>(), false))
    1247             :                 {
    1248           0 :                     bRemoved = true;
    1249           0 :                 }
    1250             :             }
    1251             : 
    1252           0 :             if (!bRemoved)
    1253             :             {
    1254             :                 //There may be another extensions at the same place
    1255             :                 dp_misc::DescriptionInfoset infoset =
    1256           0 :                     dp_misc::getDescriptionInfoset(url);
    1257             :                 OSL_ENSURE(infoset.hasDescription() && infoset.getIdentifier(),
    1258             :                            "Extension Manager: bundled and shared extensions "
    1259             :                            "must have an identifer and a version");
    1260           0 :                 if (infoset.hasDescription() &&
    1261           0 :                     infoset.getIdentifier() &&
    1262           0 :                     (! i->first.equals(*(infoset.getIdentifier()))
    1263           0 :                      || ! i->second.version.equals(infoset.getVersion())))
    1264             :                 {
    1265           0 :                     bRemoved = true;
    1266           0 :                 }
    1267             : 
    1268             :             }
    1269           0 :             if (bRemoved)
    1270             :             {
    1271           0 :                 Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
    1272           0 :                     url, i->second.mediaType, true, i->first, xCmdEnv );
    1273             :                 OSL_ASSERT(xPackage.is()); //Even if the files are removed, we must get the object.
    1274           0 :                 xPackage->revokePackage(true, xAbortChannel, xCmdEnv);
    1275           0 :                 removePackage(xPackage->getIdentifier().Value, xPackage->getName(),
    1276           0 :                               xAbortChannel, xCmdEnv);
    1277           0 :                 bModified |= true;
    1278           0 :             }
    1279             :         }
    1280           0 :         catch( const uno::Exception & e )
    1281             :         {
    1282             :             SAL_WARN("desktop.deployment", e.Message);
    1283             :         }
    1284             :     }
    1285         128 :     return bModified;
    1286             : }
    1287             : 
    1288             : 
    1289         128 : bool PackageManagerImpl::synchronizeAddedExtensions(
    1290             :     Reference<task::XAbortChannel> const & xAbortChannel,
    1291             :     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
    1292             : {
    1293         128 :     bool bModified = false;
    1294             :     OSL_ASSERT(!(m_context == "user"));
    1295             : 
    1296         128 :     ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
    1297             :     //check if the folder exist at all. The shared extension folder
    1298             :     //may not exist for a normal user.
    1299         128 :     bool bOk=true;
    1300             :     try
    1301             :     {
    1302             :         bOk = create_ucb_content(
    1303         128 :                 NULL, m_activePackages_expanded, Reference<css::ucb::XCommandEnvironment>(), false);
    1304             :     }
    1305           0 :     catch (const css::ucb::ContentCreationException&)
    1306             :     {
    1307           0 :         bOk = false;
    1308             :     }
    1309             : 
    1310         128 :     if (!bOk)
    1311           0 :         return bModified;
    1312             : 
    1313         256 :     ::ucbhelper::Content tempFolder( m_activePackages_expanded, xCmdEnv, m_xComponentContext );
    1314             :     Reference<sdbc::XResultSet> xResultSet(
    1315             :         StrTitle::createCursor( tempFolder,
    1316         256 :                                 ::ucbhelper::INCLUDE_FOLDERS_ONLY ) );
    1317             : 
    1318         256 :     while (xResultSet->next())
    1319             :     {
    1320             :         try
    1321             :         {
    1322             :             OUString title(
    1323             :                 Reference<sdbc::XRow>(
    1324           0 :                     xResultSet, UNO_QUERY_THROW )->getString(
    1325           0 :                         1 /* Title */ ) );
    1326             :             //The temporary folders of user and shared have an '_' at then end.
    1327             :             //But the name in ActivePackages.temporaryName is saved without.
    1328           0 :             OUString title2 = title;
    1329           0 :             bool bShared = (m_context == "shared");
    1330           0 :             if (bShared)
    1331             :             {
    1332             :                 OSL_ASSERT(title2.endsWith("_"));
    1333           0 :                 title2 = title2.copy(0, title2.getLength() -1);
    1334             :             }
    1335             :             OUString titleEncoded =  ::rtl::Uri::encode(
    1336             :                 title2, rtl_UriCharClassPchar,
    1337             :                 rtl_UriEncodeIgnoreEscapes,
    1338           0 :                 RTL_TEXTENCODING_UTF8);
    1339             : 
    1340             :             //It it sufficient to check for the folder name, because when the administor
    1341             :             //installed the extension it was already checked if there is one with the
    1342             :             //same identifier.
    1343           0 :             const MatchTempDir match(titleEncoded);
    1344           0 :             if (::std::find_if( id2temp.begin(), id2temp.end(), match ) ==
    1345             :                 id2temp.end())
    1346             :             {
    1347             : 
    1348             :                 // The folder was not found in the data base, so it must be
    1349             :                 // an added extension
    1350           0 :                 OUString url(m_activePackages_expanded + "/" + titleEncoded);
    1351           0 :                 OUString sExtFolder;
    1352           0 :                 if (bShared) //that is, shared
    1353             :                 {
    1354             :                     //Check if the extension was not "deleted" already which is indicated
    1355             :                     //by a xxx.tmpremoved file
    1356           0 :                     ::ucbhelper::Content contentRemoved;
    1357           0 :                     if (create_ucb_content(&contentRemoved, url + "removed",
    1358           0 :                                            Reference<XCommandEnvironment>(), false))
    1359           0 :                         continue;
    1360           0 :                     sExtFolder = getExtensionFolder(
    1361           0 :                         m_activePackages_expanded + "/" + titleEncoded + "_",
    1362           0 :                         xCmdEnv, m_xComponentContext);
    1363           0 :                     url = makeURLAppendSysPathSegment(m_activePackages_expanded, title);
    1364           0 :                     url = makeURLAppendSysPathSegment(url, sExtFolder);
    1365             :                 }
    1366           0 :                 Reference<deployment::XPackage> xPackage = m_xRegistry->bindPackage(
    1367           0 :                     url, OUString(), false, OUString(), xCmdEnv );
    1368           0 :                 if (xPackage.is())
    1369             :                 {
    1370           0 :                     OUString id = dp_misc::getIdentifier( xPackage );
    1371             : 
    1372             :                     //Prepare the database entry
    1373           0 :                     ActivePackages::Data dbData;
    1374             : 
    1375           0 :                     dbData.temporaryName = titleEncoded;
    1376           0 :                     if (bShared)
    1377           0 :                         dbData.fileName = sExtFolder;
    1378             :                     else
    1379           0 :                         dbData.fileName = title;
    1380           0 :                     dbData.mediaType = xPackage->getPackageType()->getMediaType();
    1381           0 :                     dbData.version = xPackage->getVersion();
    1382             :                     SAL_WARN_IF(
    1383             :                         dbData.version.isEmpty(), "desktop.deployment",
    1384             :                         "bundled/shared extension " << id << " at <" << url
    1385             :                             << "> has no explicit version");
    1386             : 
    1387             :                     //We provide a special command environment that will prevent
    1388             :                     //showing a license if simple-licens/@accept-by = "admin"
    1389             :                     //It will also prevent showing the license for bundled extensions
    1390             :                     //which is not supported.
    1391             :                     OSL_ASSERT(!(m_context == "user"));
    1392             : 
    1393             :                     // shall the license be suppressed?
    1394             :                     DescriptionInfoset info =
    1395           0 :                         dp_misc::getDescriptionInfoset(url);
    1396             :                     ::boost::optional<dp_misc::SimpleLicenseAttributes>
    1397           0 :                           attr = info.getSimpleLicenseAttributes();
    1398           0 :                     ExtensionProperties props(url, xCmdEnv, m_xComponentContext);
    1399           0 :                     bool bNoLicense = false;
    1400           0 :                     if (attr && attr->suppressIfRequired && props.isSuppressedLicense())
    1401           0 :                         bNoLicense = true;
    1402             : 
    1403             :                     Reference<ucb::XCommandEnvironment> licCmdEnv(
    1404           0 :                         new LicenseCommandEnv(xCmdEnv->getInteractionHandler(),
    1405           0 :                                               bNoLicense, m_context));
    1406           0 :                     sal_Int32 failedPrereq = xPackage->checkPrerequisites(
    1407           0 :                         xAbortChannel, licCmdEnv, false);
    1408             :                     //Remember that this failed. For example, the user
    1409             :                     //could have declined the license. Then the next time the
    1410             :                     //extension folder is investigated we do not want to
    1411             :                     //try to install the extension again.
    1412           0 :                     dbData.failedPrerequisites = OUString::number(failedPrereq);
    1413           0 :                     insertToActivationLayerDB(id, dbData);
    1414           0 :                     bModified |= true;
    1415           0 :                 }
    1416           0 :             }
    1417             :         }
    1418           0 :         catch (const uno::Exception & e)
    1419             :         {
    1420             :             // Looks like exceptions being caught here is not an uncommon case.
    1421             :             SAL_WARN("desktop.deployment", e.Message);
    1422             :         }
    1423             :     }
    1424         256 :     return bModified;
    1425             : }
    1426             : 
    1427         128 : sal_Bool PackageManagerImpl::synchronize(
    1428             :     Reference<task::XAbortChannel> const & xAbortChannel,
    1429             :     Reference<css::ucb::XCommandEnvironment> const & xCmdEnv)
    1430             :     throw (css::deployment::DeploymentException,
    1431             :            css::ucb::ContentCreationException,
    1432             :            css::ucb::CommandFailedException,
    1433             :            css::ucb::CommandAbortedException,
    1434             :            css::uno::RuntimeException, std::exception)
    1435             : {
    1436         128 :     check();
    1437         128 :     bool bModified = false;
    1438         128 :     if (m_context == "user")
    1439           0 :         return bModified;
    1440             :     bModified |=
    1441         128 :         synchronizeRemovedExtensions(xAbortChannel, xCmdEnv);
    1442         128 :     bModified |= synchronizeAddedExtensions(xAbortChannel, xCmdEnv);
    1443             : 
    1444         128 :     return bModified;
    1445             : }
    1446             : 
    1447           0 : Sequence< Reference<deployment::XPackage> > PackageManagerImpl::getExtensionsWithUnacceptedLicenses(
    1448             :     Reference<ucb::XCommandEnvironment> const & xCmdEnv)
    1449             :     throw (deployment::DeploymentException, RuntimeException, std::exception)
    1450             : {
    1451           0 :     ::std::vector<Reference<deployment::XPackage> > vec;
    1452             : 
    1453             :     try
    1454             :     {
    1455           0 :         const ::osl::MutexGuard guard( getMutex() );
    1456             :         // clean up activation layer, scan for zombie temp dirs:
    1457           0 :         ActivePackages::Entries id2temp( m_activePackagesDB->getEntries() );
    1458             : 
    1459           0 :         ActivePackages::Entries::const_iterator i = id2temp.begin();
    1460           0 :         bool bShared = (m_context == "shared");
    1461             : 
    1462           0 :         for (; i != id2temp.end(); ++i )
    1463             :         {
    1464             :             //Get the database entry
    1465           0 :             ActivePackages::Data const & dbData = i->second;
    1466           0 :             sal_Int32 failedPrereq = dbData.failedPrerequisites.toInt32();
    1467             :             //If the installation failed for other reason then the license then we
    1468             :             //ignore it.
    1469           0 :             if (failedPrereq ^= deployment::Prerequisites::LICENSE)
    1470           0 :                 continue;
    1471             : 
    1472             :             //Prepare the URL to the extension
    1473           0 :             OUString url = makeURL(m_activePackages, i->second.temporaryName);
    1474           0 :             if (bShared)
    1475           0 :                 url = makeURLAppendSysPathSegment( url + "_", i->second.fileName);
    1476             : 
    1477           0 :             Reference<deployment::XPackage> p = m_xRegistry->bindPackage(
    1478           0 :                 url, OUString(), false, OUString(), xCmdEnv );
    1479             : 
    1480           0 :             if (p.is())
    1481           0 :                 vec.push_back(p);
    1482             : 
    1483           0 :         }
    1484           0 :         return ::comphelper::containerToSequence(vec);
    1485             :     }
    1486           0 :     catch (const deployment::DeploymentException &)
    1487             :     {
    1488           0 :         throw;
    1489             :     }
    1490           0 :     catch (const RuntimeException&)
    1491             :     {
    1492           0 :         throw;
    1493             :     }
    1494           0 :     catch (...)
    1495             :     {
    1496           0 :         Any exc = ::cppu::getCaughtException();
    1497             :         deployment::DeploymentException de(
    1498             :             "PackageManagerImpl::getExtensionsWithUnacceptedLicenses",
    1499           0 :             static_cast<OWeakObject*>(this), exc);
    1500           0 :         exc <<= de;
    1501           0 :         ::cppu::throwException(exc);
    1502             :     }
    1503             : 
    1504           0 :     return ::comphelper::containerToSequence(vec);
    1505             : }
    1506             : 
    1507           0 : sal_Int32 PackageManagerImpl::checkPrerequisites(
    1508             :     css::uno::Reference<css::deployment::XPackage> const & extension,
    1509             :     css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel,
    1510             :     css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv )
    1511             :     throw (css::deployment::DeploymentException,
    1512             :            css::ucb::CommandFailedException,
    1513             :            css::ucb::CommandAbortedException,
    1514             :            css::lang::IllegalArgumentException,
    1515             :            css::uno::RuntimeException, std::exception)
    1516             : {
    1517             :     try
    1518             :     {
    1519           0 :         if (!extension.is())
    1520           0 :             return 0;
    1521           0 :         if (!m_context.equals(extension->getRepositoryName()))
    1522             :             throw lang::IllegalArgumentException(
    1523             :                 "PackageManagerImpl::checkPrerequisites: extension is not from this repository.",
    1524           0 :                 0, 0);
    1525             : 
    1526           0 :         ActivePackages::Data dbData;
    1527           0 :         OUString id = dp_misc::getIdentifier(extension);
    1528           0 :         if (m_activePackagesDB->get( &dbData, id, OUString()))
    1529             :         {
    1530             :             //If the license was already displayed, then do not show it again
    1531           0 :             Reference<ucb::XCommandEnvironment> _xCmdEnv = xCmdEnv;
    1532           0 :             sal_Int32 prereq = dbData.failedPrerequisites.toInt32();
    1533           0 :             if ( !(prereq & deployment::Prerequisites::LICENSE))
    1534           0 :                 _xCmdEnv = new NoLicenseCommandEnv(xCmdEnv->getInteractionHandler());
    1535             : 
    1536           0 :             sal_Int32 failedPrereq = extension->checkPrerequisites(
    1537           0 :                 xAbortChannel, _xCmdEnv, false);
    1538           0 :             dbData.failedPrerequisites = OUString::number(failedPrereq);
    1539           0 :             insertToActivationLayerDB(id, dbData);
    1540             :         }
    1541             :         else
    1542             :         {
    1543             :             throw lang::IllegalArgumentException(
    1544             :                 "PackageManagerImpl::checkPrerequisites: unknown extension",
    1545           0 :                 0, 0);
    1546             : 
    1547             :         }
    1548           0 :         return 0;
    1549             :     }
    1550           0 :     catch ( const deployment::DeploymentException& ) {
    1551           0 :         throw;
    1552           0 :     } catch ( const ucb::CommandFailedException & ) {
    1553           0 :         throw;
    1554           0 :     } catch ( const ucb::CommandAbortedException & ) {
    1555           0 :         throw;
    1556           0 :     } catch (const lang::IllegalArgumentException &) {
    1557           0 :         throw;
    1558           0 :     } catch (const uno::RuntimeException &) {
    1559           0 :         throw;
    1560           0 :     } catch (...) {
    1561           0 :         uno::Any excOccurred = ::cppu::getCaughtException();
    1562             :         deployment::DeploymentException exc(
    1563             :             "PackageManagerImpl::checkPrerequisites: exception ",
    1564           0 :             static_cast<OWeakObject*>(this), excOccurred);
    1565           0 :         throw exc;
    1566             :     }
    1567             : }
    1568             : 
    1569             : 
    1570             : 
    1571       10524 : PackageManagerImpl::CmdEnvWrapperImpl::~CmdEnvWrapperImpl()
    1572             : {
    1573       10524 : }
    1574             : 
    1575             : 
    1576        5262 : PackageManagerImpl::CmdEnvWrapperImpl::CmdEnvWrapperImpl(
    1577             :     Reference<XCommandEnvironment> const & xUserCmdEnv,
    1578             :     Reference<XProgressHandler> const & xLogFile )
    1579        5262 :     : m_xLogFile( xLogFile )
    1580             : {
    1581        5262 :     if (xUserCmdEnv.is()) {
    1582          72 :         m_xUserProgress.set( xUserCmdEnv->getProgressHandler() );
    1583          72 :         m_xUserInteractionHandler.set( xUserCmdEnv->getInteractionHandler() );
    1584             :     }
    1585        5262 : }
    1586             : 
    1587             : // XCommandEnvironment
    1588             : 
    1589             : Reference<task::XInteractionHandler>
    1590           2 : PackageManagerImpl::CmdEnvWrapperImpl::getInteractionHandler()
    1591             :     throw (RuntimeException, std::exception)
    1592             : {
    1593           2 :     return m_xUserInteractionHandler;
    1594             : }
    1595             : 
    1596             : 
    1597             : Reference<XProgressHandler>
    1598           4 : PackageManagerImpl::CmdEnvWrapperImpl::getProgressHandler()
    1599             :     throw (RuntimeException, std::exception)
    1600             : {
    1601           4 :     return this;
    1602             : }
    1603             : 
    1604             : // XProgressHandler
    1605             : 
    1606           0 : void PackageManagerImpl::CmdEnvWrapperImpl::push( Any const & Status )
    1607             :     throw (RuntimeException, std::exception)
    1608             : {
    1609           0 :     if (m_xLogFile.is())
    1610           0 :         m_xLogFile->push( Status );
    1611           0 :     if (m_xUserProgress.is())
    1612           0 :         m_xUserProgress->push( Status );
    1613           0 : }
    1614             : 
    1615             : 
    1616           2 : void PackageManagerImpl::CmdEnvWrapperImpl::update( Any const & Status )
    1617             :     throw (RuntimeException, std::exception)
    1618             : {
    1619           2 :     if (m_xLogFile.is())
    1620           2 :         m_xLogFile->update( Status );
    1621           2 :     if (m_xUserProgress.is())
    1622           0 :         m_xUserProgress->update( Status );
    1623           2 : }
    1624             : 
    1625             : 
    1626           0 : void PackageManagerImpl::CmdEnvWrapperImpl::pop() throw (RuntimeException, std::exception)
    1627             : {
    1628           0 :     if (m_xLogFile.is())
    1629           0 :         m_xLogFile->pop();
    1630           0 :     if (m_xUserProgress.is())
    1631           0 :         m_xUserProgress->pop();
    1632           0 : }
    1633             : 
    1634         420 : } // namespace dp_manager
    1635             : 
    1636             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10