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

Generated by: LCOV version 1.10