LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/desktop/source/deployment/manager - dp_manager.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 376 727 51.7 %
Date: 2013-07-09 Functions: 38 52 73.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10