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

Generated by: LCOV version 1.11