LCOV - code coverage report
Current view: top level - desktop/source/deployment/registry/component - dp_component.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 399 710 56.2 %
Date: 2014-11-03 Functions: 36 59 61.0 %
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_component.hrc"
      22             : #include "dp_backend.h"
      23             : #include "dp_platform.hxx"
      24             : #include "dp_ucb.h"
      25             : #include <rtl/string.hxx>
      26             : #include <rtl/strbuf.hxx>
      27             : #include <rtl/ustrbuf.hxx>
      28             : #include <rtl/uri.hxx>
      29             : #include <cppuhelper/exc_hlp.hxx>
      30             : #include <ucbhelper/content.hxx>
      31             : #include <comphelper/anytostring.hxx>
      32             : #include <comphelper/servicedecl.hxx>
      33             : #include <comphelper/sequence.hxx>
      34             : #include <xmlscript/xml_helper.hxx>
      35             : #include <svl/inettype.hxx>
      36             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      37             : #include <com/sun/star/container/XNameContainer.hpp>
      38             : #include <com/sun/star/container/XSet.hpp>
      39             : #include <com/sun/star/registry/XSimpleRegistry.hpp>
      40             : #include <com/sun/star/registry/XImplementationRegistration.hpp>
      41             : #include <com/sun/star/loader/XImplementationLoader.hpp>
      42             : #include <com/sun/star/io/XInputStream.hpp>
      43             : #include <com/sun/star/ucb/NameClash.hpp>
      44             : #include <com/sun/star/util/theMacroExpander.hpp>
      45             : #include <list>
      46             : #include <boost/unordered_map.hpp>
      47             : #include <vector>
      48             : #include <memory>
      49             : #include <algorithm>
      50             : #include "dp_compbackenddb.hxx"
      51             : 
      52             : using namespace ::dp_misc;
      53             : using namespace ::com::sun::star;
      54             : using namespace ::com::sun::star::uno;
      55             : using namespace ::com::sun::star::ucb;
      56             : 
      57             : namespace dp_registry {
      58             : namespace backend {
      59             : namespace component {
      60             : namespace {
      61             : 
      62             : typedef ::std::list<OUString> t_stringlist;
      63             : typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec;
      64             : 
      65             : #define IMPLEMENTATION_NAME  "com.sun.star.comp.deployment.component.PackageRegistryBackend"
      66             : 
      67             : /** return a vector of bootstrap variables which have been provided
      68             :     as command arguments.
      69             : */
      70           2 : ::std::vector<OUString> getCmdBootstrapVariables()
      71             : {
      72           2 :     ::std::vector<OUString> ret;
      73           2 :     sal_uInt32 count = osl_getCommandArgCount();
      74          20 :     for (sal_uInt32 i = 0; i < count; i++)
      75             :     {
      76          18 :         OUString arg;
      77          18 :         osl_getCommandArg(i, &arg.pData);
      78          18 :         if (arg.match("-env:"))
      79           6 :             ret.push_back(arg);
      80          18 :     }
      81           2 :     return ret;
      82             : }
      83             : 
      84           2 : bool jarManifestHeaderPresent(
      85             :     OUString const & url, OUString const & name,
      86             :     Reference<XCommandEnvironment> const & xCmdEnv )
      87             : {
      88           2 :     OUStringBuffer buf;
      89           2 :     buf.appendAscii( "vnd.sun.star.zip://" );
      90             :     buf.append(
      91             :         ::rtl::Uri::encode(
      92             :             url, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes,
      93           2 :             RTL_TEXTENCODING_UTF8 ) );
      94           2 :     buf.appendAscii( "/META-INF/MANIFEST.MF" );
      95           4 :     ::ucbhelper::Content manifestContent;
      96           4 :     OUString line;
      97             :     return
      98             :         create_ucb_content(
      99             :             &manifestContent, buf.makeStringAndClear(), xCmdEnv,
     100           8 :             false /* no throw */ )
     101           8 :         && readLine( &line, name, manifestContent, RTL_TEXTENCODING_ASCII_US );
     102             : }
     103             : 
     104             : 
     105         490 : class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
     106             : {
     107           4 :     class ComponentPackageImpl : public ::dp_registry::backend::Package
     108             :     {
     109             :         BackendImpl * getMyBackend() const;
     110             : 
     111             :         const OUString m_loader;
     112             : 
     113             :         enum reg {
     114             :             REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED, REG_MAYBE_REGISTERED
     115             :         } m_registered;
     116             : 
     117             :         void getComponentInfo(
     118             :             ComponentBackendDb::Data * data,
     119             :             std::vector< css::uno::Reference< css::uno::XInterface > > *
     120             :                 factories,
     121             :             Reference<XComponentContext> const & xContext );
     122             : 
     123             :         void componentLiveInsertion(
     124             :             ComponentBackendDb::Data const & data,
     125             :             std::vector< css::uno::Reference< css::uno::XInterface > > const &
     126             :                 factories);
     127             : 
     128             :         void componentLiveRemoval(ComponentBackendDb::Data const & data);
     129             : 
     130             :         virtual void SAL_CALL disposing() SAL_OVERRIDE;
     131             : 
     132             :         // Package
     133             :         virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
     134             :             ::osl::ResettableMutexGuard & guard,
     135             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     136             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     137             :         virtual void processPackage_(
     138             :             ::osl::ResettableMutexGuard & guard,
     139             :             bool registerPackage,
     140             :             bool startup,
     141             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     142             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     143             : 
     144             :         const Reference<registry::XSimpleRegistry> getRDB() const;
     145             : 
     146             :     public:
     147             :         ComponentPackageImpl(
     148             :             ::rtl::Reference<PackageRegistryBackend> const & myBackend,
     149             :             OUString const & url, OUString const & name,
     150             :             Reference<deployment::XPackageTypeInfo> const & xPackageType,
     151             :             OUString const & loader, bool bRemoved,
     152             :             OUString const & identifier);
     153             :     };
     154             :     friend class ComponentPackageImpl;
     155             : 
     156           0 :     class ComponentsPackageImpl : public ::dp_registry::backend::Package
     157             :     {
     158             :         BackendImpl * getMyBackend() const;
     159             : 
     160             :         // Package
     161             :         virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
     162             :             ::osl::ResettableMutexGuard & guard,
     163             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     164             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     165             :         virtual void processPackage_(
     166             :             ::osl::ResettableMutexGuard & guard,
     167             :             bool registerPackage,
     168             :             bool startup,
     169             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     170             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     171             :     public:
     172             :         ComponentsPackageImpl(
     173             :             ::rtl::Reference<PackageRegistryBackend> const & myBackend,
     174             :             OUString const & url, OUString const & name,
     175             :             Reference<deployment::XPackageTypeInfo> const & xPackageType,
     176             :             bool bRemoved, OUString const & identifier);
     177             :     };
     178             :     friend class ComponentsPackageImpl;
     179             : 
     180           0 :     class TypelibraryPackageImpl : public ::dp_registry::backend::Package
     181             :     {
     182             :         BackendImpl * getMyBackend() const;
     183             : 
     184             :         const bool m_jarFile;
     185             : 
     186             :         virtual void SAL_CALL disposing() SAL_OVERRIDE;
     187             : 
     188             :         // Package
     189             :         virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
     190             :             ::osl::ResettableMutexGuard & guard,
     191             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     192             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     193             :         virtual void processPackage_(
     194             :             ::osl::ResettableMutexGuard & guard,
     195             :             bool registerPackage,
     196             :             bool startup,
     197             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     198             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     199             : 
     200             :     public:
     201             :         TypelibraryPackageImpl(
     202             :             ::rtl::Reference<PackageRegistryBackend> const & myBackend,
     203             :             OUString const & url, OUString const & name,
     204             :             Reference<deployment::XPackageTypeInfo> const & xPackageType,
     205             :             bool jarFile, bool bRemoved,
     206             :             OUString const & identifier);
     207             :     };
     208             :     friend class TypelibraryPackageImpl;
     209             : 
     210             :     /** Serves for unregistering packages that were registered on a
     211             :         different platform. This can happen if one has remotely mounted
     212             :         /home, for example.
     213             :      */
     214           0 :     class OtherPlatformPackageImpl : public ::dp_registry::backend::Package
     215             :     {
     216             :     public:
     217             :         OtherPlatformPackageImpl(
     218             :             ::rtl::Reference<PackageRegistryBackend> const & myBackend,
     219             :             OUString const & url, OUString const & name,
     220             :             Reference<deployment::XPackageTypeInfo> const & xPackageType,
     221             :             bool bRemoved, OUString const & identifier, OUString const& rPlatform);
     222             : 
     223             :     private:
     224             :         BackendImpl * getMyBackend() const;
     225             : 
     226             :         const Reference<registry::XSimpleRegistry> impl_openRDB() const;
     227             :         const Reference<XInterface> impl_createInstance(OUString const& rService) const;
     228             : 
     229             :         // Package
     230             :         virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
     231             :             ::osl::ResettableMutexGuard & guard,
     232             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     233             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     234             :         virtual void processPackage_(
     235             :             ::osl::ResettableMutexGuard & guard,
     236             :             bool registerPackage,
     237             :             bool startup,
     238             :             ::rtl::Reference<AbortChannel> const & abortChannel,
     239             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     240             : 
     241             :     private:
     242             :         OUString const m_aPlatform;
     243             :     };
     244             :     friend class OtherPlatformPackageImpl;
     245             : 
     246             :     t_stringlist m_jar_typelibs;
     247             :     t_stringlist m_rdb_typelibs;
     248             :     t_stringlist m_components;
     249             : 
     250             :     enum RcItem { RCITEM_JAR_TYPELIB, RCITEM_RDB_TYPELIB, RCITEM_COMPONENTS };
     251             : 
     252           4 :     t_stringlist & getRcItemList( RcItem kind ) {
     253           4 :         switch (kind)
     254             :         {
     255             :         case RCITEM_JAR_TYPELIB:
     256           4 :             return m_jar_typelibs;
     257             :         case RCITEM_RDB_TYPELIB:
     258           0 :             return m_rdb_typelibs;
     259             :         default: // case RCITEM_COMPONENTS
     260           0 :             return m_components;
     261             :         }
     262             :     }
     263             : 
     264             :     bool m_unorc_inited;
     265             :     bool m_unorc_modified;
     266             :     bool bSwitchedRdbFiles;
     267             : 
     268             :     typedef ::boost::unordered_map< OUString, Reference<XInterface>,
     269             :                              OUStringHash > t_string2object;
     270             :     t_string2object m_backendObjects;
     271             : 
     272             :     // PackageRegistryBackend
     273             :     virtual Reference<deployment::XPackage> bindPackage_(
     274             :         OUString const & url, OUString const & mediaType,
     275             :         bool bRemoved, OUString const & identifier,
     276             :         Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     277             : 
     278             :     virtual void SAL_CALL disposing() SAL_OVERRIDE;
     279             : 
     280             :     const Reference<deployment::XPackageTypeInfo> m_xDynComponentTypeInfo;
     281             :     const Reference<deployment::XPackageTypeInfo> m_xJavaComponentTypeInfo;
     282             :     const Reference<deployment::XPackageTypeInfo> m_xPythonComponentTypeInfo;
     283             :     const Reference<deployment::XPackageTypeInfo> m_xComponentsTypeInfo;
     284             :     const Reference<deployment::XPackageTypeInfo> m_xRDBTypelibTypeInfo;
     285             :     const Reference<deployment::XPackageTypeInfo> m_xJavaTypelibTypeInfo;
     286             :     Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
     287             : 
     288             :     OUString m_commonRDB;
     289             :     OUString m_nativeRDB;
     290             : 
     291             :     //URLs of the original rdbs (before any switching):
     292             :     OUString m_commonRDB_orig;
     293             :     OUString m_nativeRDB_orig;
     294             : 
     295             :     std::unique_ptr<ComponentBackendDb> m_backendDb;
     296             : 
     297             :     void addDataToDb(OUString const & url, ComponentBackendDb::Data const & data);
     298             :     ComponentBackendDb::Data readDataFromDb(OUString const & url);
     299             :     void revokeEntryFromDb(OUString const & url);
     300             : 
     301             :     Reference<registry::XSimpleRegistry> m_xCommonRDB;
     302             :     Reference<registry::XSimpleRegistry> m_xNativeRDB;
     303             : 
     304             :     void unorc_verify_init( Reference<XCommandEnvironment> const & xCmdEnv );
     305             :     void unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv );
     306             : 
     307             :     Reference<XInterface> getObject( OUString const & id );
     308             :     Reference<XInterface> insertObject(
     309             :         OUString const & id, Reference<XInterface> const & xObject );
     310             :     void releaseObject( OUString const & id );
     311             : 
     312             :     bool addToUnoRc( RcItem kind, OUString const & url,
     313             :                      Reference<XCommandEnvironment> const & xCmdEnv );
     314             :     bool removeFromUnoRc( RcItem kind, OUString const & url,
     315             :                           Reference<XCommandEnvironment> const & xCmdEnv );
     316             :     bool hasInUnoRc( RcItem kind, OUString const & url );
     317             : 
     318             :     css::uno::Reference< css::uno::XComponentContext > getRootContext() const;
     319             : 
     320             : public:
     321             :     BackendImpl( Sequence<Any> const & args,
     322             :                  Reference<XComponentContext> const & xComponentContext );
     323             : 
     324             :     // XPackageRegistry
     325             :     virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
     326             :     getSupportedPackageTypes() throw (RuntimeException, std::exception) SAL_OVERRIDE;
     327             : 
     328             :     virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
     329             :         throw (deployment::DeploymentException,
     330             :                uno::RuntimeException, std::exception) SAL_OVERRIDE;
     331             : 
     332             :     using PackageRegistryBackend::disposing;
     333             : 
     334             :     //Will be called from ComponentPackageImpl
     335             :     void initServiceRdbFiles();
     336             : };
     337             : 
     338             : 
     339             : 
     340           2 : BackendImpl::ComponentPackageImpl::ComponentPackageImpl(
     341             :     ::rtl::Reference<PackageRegistryBackend> const & myBackend,
     342             :     OUString const & url, OUString const & name,
     343             :     Reference<deployment::XPackageTypeInfo> const & xPackageType,
     344             :     OUString const & loader, bool bRemoved,
     345             :     OUString const & identifier)
     346             :     : Package( myBackend, url, name, name /* display-name */,
     347             :                xPackageType, bRemoved, identifier),
     348             :       m_loader( loader ),
     349           2 :       m_registered( REG_UNINIT )
     350           2 : {}
     351             : 
     352             : const Reference<registry::XSimpleRegistry>
     353           6 : BackendImpl::ComponentPackageImpl::getRDB() const
     354             : {
     355           6 :     BackendImpl * that = getMyBackend();
     356             : 
     357             :     //Late "initialization" of the services rdb files
     358             :     //This is to prevent problems when running several
     359             :     //instances of OOo with root rights in parallel. This
     360             :     //would otherwise cause problems when copying the rdbs.
     361             :     //See  http://qa.openoffice.org/issues/show_bug.cgi?id=99257
     362             :     {
     363           6 :         const ::osl::MutexGuard guard( getMutex() );
     364           6 :         if (!that->bSwitchedRdbFiles)
     365             :         {
     366           2 :             that->bSwitchedRdbFiles = true;
     367           2 :             that->initServiceRdbFiles();
     368           6 :         }
     369             :     }
     370           6 :     if ( m_loader == "com.sun.star.loader.SharedLibrary" )
     371           0 :         return that->m_xNativeRDB;
     372             :     else
     373           6 :         return that->m_xCommonRDB;
     374             : }
     375             : 
     376          16 : BackendImpl * BackendImpl::ComponentPackageImpl::getMyBackend() const
     377             : {
     378          16 :     BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
     379          16 :     if (NULL == pBackend)
     380             :     {
     381             :         //Throws a DisposedException
     382           0 :         check();
     383             :         //We should never get here...
     384             :         throw RuntimeException(
     385             :             "Failed to get the BackendImpl",
     386           0 :             static_cast<OWeakObject*>(const_cast<ComponentPackageImpl *>(this)));
     387             :     }
     388          16 :     return pBackend;
     389             : }
     390             : 
     391             : 
     392             : 
     393           2 : void BackendImpl::ComponentPackageImpl::disposing()
     394             : {
     395           2 :     Package::disposing();
     396           2 : }
     397             : 
     398             : 
     399           0 : void BackendImpl::TypelibraryPackageImpl::disposing()
     400             : {
     401           0 :     Package::disposing();
     402           0 : }
     403             : 
     404             : 
     405         490 : void BackendImpl::disposing()
     406             : {
     407             :     try {
     408         490 :         m_backendObjects = t_string2object();
     409         490 :         if (m_xNativeRDB.is()) {
     410           2 :             m_xNativeRDB->close();
     411           2 :             m_xNativeRDB.clear();
     412             :         }
     413         490 :         if (m_xCommonRDB.is()) {
     414           2 :             m_xCommonRDB->close();
     415           2 :             m_xCommonRDB.clear();
     416             :         }
     417         490 :         unorc_flush( Reference<XCommandEnvironment>() );
     418             : 
     419         490 :         PackageRegistryBackend::disposing();
     420             :     }
     421           0 :     catch (const RuntimeException &) {
     422           0 :         throw;
     423             :     }
     424           0 :     catch (const Exception &) {
     425           0 :         Any exc( ::cppu::getCaughtException() );
     426             :         throw lang::WrappedTargetRuntimeException(
     427             :             "caught unexpected exception while disposing...",
     428           0 :             static_cast<OWeakObject *>(this), exc );
     429             :     }
     430         490 : }
     431             : 
     432             : 
     433           2 : void BackendImpl::initServiceRdbFiles()
     434             : {
     435           2 :     const Reference<XCommandEnvironment> xCmdEnv;
     436             : 
     437           4 :     ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv, m_xComponentContext );
     438           4 :     ::ucbhelper::Content oldRDB;
     439             :     // switch common rdb:
     440           2 :     if (!m_commonRDB_orig.isEmpty())
     441             :     {
     442             :         create_ucb_content(
     443           0 :             &oldRDB, makeURL( getCachePath(), m_commonRDB_orig),
     444           0 :             xCmdEnv, false /* no throw */ );
     445             :     }
     446           2 :     m_commonRDB = m_commonRDB_orig == "common.rdb" ? OUString("common_.rdb") : OUString("common.rdb");
     447           2 :     if (oldRDB.get().is())
     448             :     {
     449           0 :         if (! cacheDir.transferContent(
     450             :                 oldRDB, ::ucbhelper::InsertOperation_COPY,
     451           0 :                 m_commonRDB, NameClash::OVERWRITE ))
     452             :         {
     453             : 
     454           0 :             throw RuntimeException( "UCB transferContent() failed!", 0 );
     455             :         }
     456           0 :         oldRDB = ::ucbhelper::Content();
     457             :     }
     458             :     // switch native rdb:
     459           2 :     if (!m_nativeRDB_orig.isEmpty())
     460             :     {
     461             :         create_ucb_content(
     462           0 :             &oldRDB, makeURL(getCachePath(), m_nativeRDB_orig),
     463           0 :             xCmdEnv, false /* no throw */ );
     464             :     }
     465           4 :     const OUString plt_rdb( getPlatformString() + ".rdb" );
     466           4 :     const OUString plt_rdb_( getPlatformString() + "_.rdb" );
     467           2 :     m_nativeRDB = (m_nativeRDB_orig == plt_rdb ) ? plt_rdb_ : plt_rdb;
     468           2 :     if (oldRDB.get().is())
     469             :     {
     470           0 :         if (! cacheDir.transferContent(
     471             :                 oldRDB, ::ucbhelper::InsertOperation_COPY,
     472           0 :                 m_nativeRDB, NameClash::OVERWRITE ))
     473           0 :             throw RuntimeException( "UCB transferContent() failed!", 0 );
     474             :     }
     475             : 
     476             :     // UNO is bootstrapped, flush for next process start:
     477           2 :     m_unorc_modified = true;
     478           2 :     unorc_flush( Reference<XCommandEnvironment>() );
     479             : 
     480             : 
     481             :     // common rdb for java, native rdb for shared lib components
     482           2 :     if (!m_commonRDB.isEmpty()) {
     483             :         m_xCommonRDB.set(
     484           2 :             m_xComponentContext->getServiceManager()
     485           4 :             ->createInstanceWithContext(
     486             :             "com.sun.star.registry.SimpleRegistry",
     487           2 :             m_xComponentContext ), UNO_QUERY_THROW );
     488           2 :         m_xCommonRDB->open(
     489           2 :             makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB ),
     490           4 :             false, true);
     491             :     }
     492           2 :     if (!m_nativeRDB.isEmpty()) {
     493             :         m_xNativeRDB.set(
     494           2 :             m_xComponentContext->getServiceManager()
     495           4 :             ->createInstanceWithContext(
     496             :             "com.sun.star.registry.SimpleRegistry",
     497           2 :             m_xComponentContext ), UNO_QUERY_THROW );
     498           2 :         m_xNativeRDB->open(
     499           2 :             makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB ),
     500           4 :             false, true);
     501           2 :     }
     502           2 : }
     503             : 
     504         490 : BackendImpl::BackendImpl(
     505             :     Sequence<Any> const & args,
     506             :     Reference<XComponentContext> const & xComponentContext )
     507             :     : PackageRegistryBackend( args, xComponentContext ),
     508             :       m_unorc_inited( false ),
     509             :       m_unorc_modified( false ),
     510             :       bSwitchedRdbFiles(false),
     511             :       m_xDynComponentTypeInfo( new Package::TypeInfo(
     512         980 :              "application/vnd.sun.star.uno-component;type=native;platform=" +
     513         490 :                                    getPlatformString(),
     514         980 :                                    OUString("*") + OUString(SAL_DLLEXTENSION),
     515             :                                    getResourceString(RID_STR_DYN_COMPONENT),
     516         490 :                                    RID_IMG_COMPONENT) ),
     517             :       m_xJavaComponentTypeInfo( new Package::TypeInfo(
     518             :              "application/vnd.sun.star.uno-component;type=Java",
     519             :                                     "*.jar",
     520             :                                     getResourceString(RID_STR_JAVA_COMPONENT),
     521         490 :                                     RID_IMG_JAVA_COMPONENT) ),
     522             :       m_xPythonComponentTypeInfo( new Package::TypeInfo(
     523             :              "application/vnd.sun.star.uno-component;type=Python",
     524             :                                       "*.py",
     525             :                                       getResourceString(
     526             :                                           RID_STR_PYTHON_COMPONENT),
     527         490 :                                       RID_IMG_COMPONENT ) ),
     528             :       m_xComponentsTypeInfo( new Package::TypeInfo(
     529             :                                  "application/vnd.sun.star.uno-components",
     530             :                                  "*.components",
     531             :                                  getResourceString(RID_STR_COMPONENTS),
     532         490 :                                  RID_IMG_COMPONENT ) ),
     533             :       m_xRDBTypelibTypeInfo( new Package::TypeInfo(
     534             :              "application/vnd.sun.star.uno-typelibrary;type=RDB",
     535             :                                  "*.rdb",
     536             :                                  getResourceString(RID_STR_RDB_TYPELIB),
     537         490 :                                  RID_IMG_TYPELIB ) ),
     538             :       m_xJavaTypelibTypeInfo( new Package::TypeInfo(
     539             :              "application/vnd.sun.star.uno-typelibrary;type=Java",
     540             :                                   "*.jar",
     541             :                                   getResourceString(RID_STR_JAVA_TYPELIB),
     542         490 :                                   RID_IMG_JAVA_TYPELIB ) ),
     543        5390 :       m_typeInfos( 6 )
     544             : {
     545         490 :     m_typeInfos[ 0 ] = m_xDynComponentTypeInfo;
     546         490 :     m_typeInfos[ 1 ] = m_xJavaComponentTypeInfo;
     547         490 :     m_typeInfos[ 2 ] = m_xPythonComponentTypeInfo;
     548         490 :     m_typeInfos[ 3 ] = m_xComponentsTypeInfo;
     549         490 :     m_typeInfos[ 4 ] = m_xRDBTypelibTypeInfo;
     550         490 :     m_typeInfos[ 5 ] = m_xJavaTypelibTypeInfo;
     551             : 
     552         490 :     const Reference<XCommandEnvironment> xCmdEnv;
     553             : 
     554         490 :     if (transientMode())
     555             :     {
     556             :         // in-mem rdbs:
     557             :         // common rdb for java, native rdb for shared lib components
     558             :         m_xCommonRDB.set(
     559           0 :             xComponentContext->getServiceManager()->createInstanceWithContext(
     560             :                 "com.sun.star.registry.SimpleRegistry",
     561           0 :                 xComponentContext ), UNO_QUERY_THROW );
     562           0 :         m_xCommonRDB->open( OUString() /* in-mem */,
     563           0 :                             false /* ! read-only */, true /* create */ );
     564             :         m_xNativeRDB.set(
     565           0 :             xComponentContext->getServiceManager()->createInstanceWithContext(
     566             :                 "com.sun.star.registry.SimpleRegistry",
     567           0 :                 xComponentContext ), UNO_QUERY_THROW );
     568           0 :         m_xNativeRDB->open( OUString() /* in-mem */,
     569           0 :                             false /* ! read-only */, true /* create */ );
     570             :     }
     571             :     else
     572             :     {
     573         490 :         unorc_verify_init( xCmdEnv );
     574         490 :         OUString dbFile = makeURL(getCachePath(), "backenddb.xml");
     575             :         m_backendDb.reset(
     576         490 :             new ComponentBackendDb(getComponentContext(), dbFile));
     577         490 :     }
     578         490 : }
     579             : 
     580           2 : void BackendImpl::addDataToDb(
     581             :     OUString const & url, ComponentBackendDb::Data const & data)
     582             : {
     583           2 :     if (m_backendDb.get())
     584           2 :         m_backendDb->addEntry(url, data);
     585           2 : }
     586             : 
     587           2 : ComponentBackendDb::Data BackendImpl::readDataFromDb(OUString const & url)
     588             : {
     589           2 :     ComponentBackendDb::Data data;
     590           2 :     if (m_backendDb.get())
     591           2 :         data = m_backendDb->getEntry(url);
     592           2 :     return data;
     593             : }
     594             : 
     595           2 : void BackendImpl::revokeEntryFromDb(OUString const & url)
     596             : {
     597           2 :     if (m_backendDb.get())
     598           2 :         m_backendDb->revokeEntry(url);
     599           2 : }
     600             : 
     601             : // XPackageRegistry
     602             : 
     603             : Sequence< Reference<deployment::XPackageTypeInfo> >
     604         490 : BackendImpl::getSupportedPackageTypes() throw (RuntimeException, std::exception)
     605             : {
     606         490 :     return m_typeInfos;
     607             : }
     608             : 
     609           2 : void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
     610             :         throw (deployment::DeploymentException,
     611             :                uno::RuntimeException, std::exception)
     612             : {
     613           2 :     if (m_backendDb.get())
     614           2 :         m_backendDb->removeEntry(url);
     615           2 : }
     616             : 
     617             : // PackageRegistryBackend
     618             : 
     619           8 : Reference<deployment::XPackage> BackendImpl::bindPackage_(
     620             :     OUString const & url, OUString const & mediaType_,
     621             :     bool bRemoved, OUString const & identifier,
     622             :     Reference<XCommandEnvironment> const & xCmdEnv )
     623             : {
     624           8 :     OUString mediaType(mediaType_);
     625           8 :     if ( mediaType.isEmpty() || mediaType == "application/vnd.sun.star.uno-component" || mediaType == "application/vnd.sun.star.uno-typelibrary" )
     626             :     {
     627             :         // detect exact media-type:
     628           6 :         ::ucbhelper::Content ucbContent;
     629           6 :         if (create_ucb_content( &ucbContent, url, xCmdEnv )) {
     630           6 :             const OUString title( StrTitle::getTitle( ucbContent ) );
     631           6 :             if (title.endsWithIgnoreAsciiCase(SAL_DLLEXTENSION))
     632             :             {
     633           0 :                 mediaType = "application/vnd.sun.star.uno-component;type=native;platform=" +
     634           0 :                     getPlatformString();
     635             :             }
     636           6 :             else if (title.endsWithIgnoreAsciiCase(".jar"))
     637             :             {
     638           0 :                 if (jarManifestHeaderPresent(
     639           0 :                         url, "RegistrationClassName", xCmdEnv ))
     640           0 :                     mediaType = "application/vnd.sun.star.uno-component;type=Java";
     641           0 :                 if (mediaType.isEmpty())
     642           0 :                     mediaType = "application/vnd.sun.star.uno-typelibrary;type=Java";
     643             :             }
     644           6 :             else if (title.endsWithIgnoreAsciiCase(".py"))
     645           0 :                 mediaType = "application/vnd.sun.star.uno-component;type=Python";
     646           6 :             else if (title.endsWithIgnoreAsciiCase(".rdb"))
     647           0 :                 mediaType = "application/vnd.sun.star.uno-typelibrary;type=RDB";
     648             :         }
     649           6 :         if (mediaType.isEmpty())
     650             :             throw lang::IllegalArgumentException(
     651          12 :                 StrCannotDetectMediaType::get() + url,
     652          18 :                 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
     653             :     }
     654             : 
     655           4 :     OUString type, subType;
     656           4 :     INetContentTypeParameterList params;
     657           2 :     if (INetContentTypes::parse( mediaType, type, subType, &params ))
     658             :     {
     659           2 :         if (type.equalsIgnoreAsciiCase("application"))
     660             :         {
     661           2 :             OUString name;
     662           2 :             if (!bRemoved)
     663             :             {
     664           2 :                 ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
     665           2 :                 name = StrTitle::getTitle( ucbContent );
     666             :             }
     667             : 
     668           2 :             if (subType.equalsIgnoreAsciiCase("vnd.sun.star.uno-component"))
     669             :             {
     670             :                 // xxx todo: probe and evaluate component xml description
     671             : 
     672           2 :                 INetContentTypeParameter const * param = params.find(OString("platform"));
     673           2 :                 bool bPlatformFits(param == 0);
     674           2 :                 OUString aPlatform;
     675           2 :                 if (!bPlatformFits) // platform is specified, we have to check
     676             :                 {
     677           0 :                     aPlatform = param->m_sValue;
     678           0 :                     bPlatformFits = platform_fits(aPlatform);
     679             :                 }
     680             :                 // If the package is being removed, do not care whether
     681             :                 // platform fits. We won't be using it anyway.
     682           2 :                 if (bPlatformFits || bRemoved) {
     683           2 :                     param = params.find(OString("type"));
     684           2 :                     if (param != 0)
     685             :                     {
     686           2 :                         OUString const & value = param->m_sValue;
     687           2 :                         if (value.equalsIgnoreAsciiCase("native")) {
     688           0 :                             if (bPlatformFits)
     689             :                                 return new BackendImpl::ComponentPackageImpl(
     690             :                                     this, url, name, m_xDynComponentTypeInfo,
     691             :                                     "com.sun.star.loader.SharedLibrary",
     692           0 :                                     bRemoved, identifier);
     693             :                             else
     694             :                                 return new BackendImpl::OtherPlatformPackageImpl(
     695             :                                     this, url, name, m_xDynComponentTypeInfo,
     696           0 :                                     bRemoved, identifier, aPlatform);
     697             :                         }
     698           2 :                         if (value.equalsIgnoreAsciiCase("Java")) {
     699             :                             return new BackendImpl::ComponentPackageImpl(
     700             :                                 this, url, name, m_xJavaComponentTypeInfo,
     701             :                                 "com.sun.star.loader.Java2",
     702           2 :                                 bRemoved, identifier);
     703             :                         }
     704           0 :                         if (value.equalsIgnoreAsciiCase("Python")) {
     705             :                             return new BackendImpl::ComponentPackageImpl(
     706             :                                 this, url, name, m_xPythonComponentTypeInfo,
     707             :                                 "com.sun.star.loader.Python",
     708           0 :                                 bRemoved, identifier);
     709             :                         }
     710             :                     }
     711           0 :                 }
     712             :             }
     713           0 :             else if (subType.equalsIgnoreAsciiCase("vnd.sun.star.uno-components"))
     714             :             {
     715           0 :                 INetContentTypeParameter const * param = params.find(OString("platform"));
     716           0 :                 if (param == 0 || platform_fits( param->m_sValue )) {
     717             :                     return new BackendImpl::ComponentsPackageImpl(
     718             :                         this, url, name, m_xComponentsTypeInfo, bRemoved,
     719           0 :                         identifier);
     720             :                 }
     721             :             }
     722           0 :             else if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.uno-typelibrary"))
     723             :             {
     724           0 :                 INetContentTypeParameter const * param = params.find(OString("type"));
     725           0 :                 if (param != 0) {
     726           0 :                     OUString const & value = param->m_sValue;
     727           0 :                     if (value.equalsIgnoreAsciiCase("RDB"))
     728             :                     {
     729             :                         return new BackendImpl::TypelibraryPackageImpl(
     730             :                             this, url, name, m_xRDBTypelibTypeInfo,
     731           0 :                             false /* rdb */, bRemoved, identifier);
     732             :                     }
     733           0 :                     if (value.equalsIgnoreAsciiCase("Java")) {
     734             :                         return new BackendImpl::TypelibraryPackageImpl(
     735             :                             this, url, name, m_xJavaTypelibTypeInfo,
     736           0 :                             true /* jar */, bRemoved, identifier);
     737             :                     }
     738             :                 }
     739           0 :             }
     740             :         }
     741             :     }
     742             :     throw lang::IllegalArgumentException(
     743           0 :         StrUnsupportedMediaType::get() + mediaType,
     744             :         static_cast<OWeakObject *>(this),
     745           8 :         static_cast<sal_Int16>(-1) );
     746             : }
     747             : 
     748             : 
     749             : 
     750         494 : void BackendImpl::unorc_verify_init(
     751             :     Reference<XCommandEnvironment> const & xCmdEnv )
     752             : {
     753         494 :     if (transientMode())
     754         494 :         return;
     755         494 :     const ::osl::MutexGuard guard( getMutex() );
     756         494 :     if (! m_unorc_inited)
     757             :     {
     758             :         // common rc:
     759         490 :         ::ucbhelper::Content ucb_content;
     760         980 :         if (create_ucb_content(
     761             :                 &ucb_content,
     762         490 :                 makeURL( getCachePath(), "unorc" ),
     763        1470 :                 xCmdEnv, false /* no throw */ ))
     764             :         {
     765           0 :             OUString line;
     766           0 :             if (readLine( &line, "UNO_JAVA_CLASSPATH=", ucb_content,
     767           0 :                           RTL_TEXTENCODING_UTF8 ))
     768             :             {
     769           0 :                 sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1;
     770           0 :                 do {
     771           0 :                     OUString token( line.getToken( 0, ' ', index ).trim() );
     772           0 :                     if (!token.isEmpty())
     773             :                     {
     774           0 :                         if (create_ucb_content(
     775             :                                 0, expandUnoRcTerm(token), xCmdEnv,
     776           0 :                                 false /* no throw */ ))
     777             :                         {
     778             :                             //The jar file may not exist anymore if a shared or bundled
     779             :                             //extension was removed, but it can still be in the unorc
     780             :                             //After running XExtensionManager::synchronize, the unorc is
     781             :                             //cleaned up
     782           0 :                             m_jar_typelibs.push_back( token );
     783             :                         }
     784           0 :                     }
     785             :                 }
     786           0 :                 while (index >= 0);
     787             :             }
     788           0 :             if (readLine( &line, "UNO_TYPES=", ucb_content,
     789           0 :                           RTL_TEXTENCODING_UTF8 )) {
     790           0 :                 sal_Int32 index = sizeof ("UNO_TYPES=") - 1;
     791           0 :                 do {
     792           0 :                     OUString token( line.getToken( 0, ' ', index ).trim() );
     793           0 :                     if (!token.isEmpty())
     794             :                     {
     795           0 :                         if (token[ 0 ] == '?')
     796           0 :                             token = token.copy( 1 );
     797           0 :                          if (create_ucb_content(
     798             :                                 0, expandUnoRcTerm(token), xCmdEnv,
     799           0 :                                 false /* no throw */ ))
     800             :                          {
     801             :                              //The RDB file may not exist anymore if a shared or bundled
     802             :                              //extension was removed, but it can still be in the unorc.
     803             :                              //After running XExtensionManager::synchronize, the unorc is
     804             :                              //cleaned up
     805           0 :                              m_rdb_typelibs.push_back( token );
     806             :                          }
     807           0 :                     }
     808             :                 }
     809           0 :                 while (index >= 0);
     810             :             }
     811           0 :             if (readLine( &line, "UNO_SERVICES=", ucb_content,
     812           0 :                           RTL_TEXTENCODING_UTF8 ))
     813             :             {
     814             :                 // The UNO_SERVICES line always has the BNF form
     815             :                 //  "UNO_SERVICES="
     816             :                 //  ("?$ORIGIN/" <common-rdb>)?                        -- first
     817             :                 //  "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"?       -- second
     818             :                 //  ("?" ("BUNDLED_EXTENSIONS" |                       -- third
     819             :                 //   "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE")
     820             :                 //   ...)*
     821             :                 // so can unambiguously be split into its thre parts:
     822           0 :                 int state = 1;
     823           0 :                 for (sal_Int32 i = RTL_CONSTASCII_LENGTH("UNO_SERVICES=");
     824           0 :                      i >= 0;)
     825             :                 {
     826           0 :                     OUString token(line.getToken(0, ' ', i));
     827           0 :                     if (!token.isEmpty())
     828             :                     {
     829           0 :                         if (state == 1 && token.match("?$ORIGIN/"))
     830             :                         {
     831           0 :                             m_commonRDB_orig = token.copy(
     832           0 :                                 RTL_CONSTASCII_LENGTH("?$ORIGIN/"));
     833           0 :                             state = 2;
     834             :                         }
     835           0 :                         else if ( state <= 2 && token == "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" )
     836             :                         {
     837           0 :                             state = 3;
     838             :                         }
     839             :                         else
     840             :                         {
     841           0 :                             if (token[0] == '?')
     842             :                             {
     843           0 :                                 token = token.copy(1);
     844             :                             }
     845           0 :                             m_components.push_back(token);
     846           0 :                             state = 3;
     847             :                         }
     848             :                     }
     849           0 :                 }
     850             :             }
     851             : 
     852             :             // native rc:
     853           0 :             if (create_ucb_content(
     854             :                     &ucb_content,
     855           0 :                     makeURL( getCachePath(), getPlatformString() + "rc"),
     856           0 :                     xCmdEnv, false /* no throw */ )) {
     857           0 :                 if (readLine( &line, "UNO_SERVICES=", ucb_content,
     858           0 :                               RTL_TEXTENCODING_UTF8 )) {
     859           0 :                     m_nativeRDB_orig = line.copy(
     860           0 :                         sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 );
     861             :                 }
     862           0 :             }
     863             :         }
     864         490 :         m_unorc_modified = false;
     865         490 :         m_unorc_inited = true;
     866         494 :     }
     867             : }
     868             : 
     869             : 
     870         496 : void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv )
     871             : {
     872         496 :     if (transientMode())
     873         490 :         return;
     874         496 :     if (!m_unorc_inited || !m_unorc_modified)
     875         490 :         return;
     876             : 
     877           6 :     OStringBuffer buf;
     878             : 
     879           6 :     buf.append("ORIGIN=");
     880          12 :     OUString sOrigin = dp_misc::makeRcTerm(m_cachePath);
     881          12 :     OString osOrigin = OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8);
     882           6 :     buf.append(osOrigin);
     883           6 :     buf.append(LF);
     884             : 
     885           6 :     if (! m_jar_typelibs.empty())
     886             :     {
     887           2 :         t_stringlist::const_iterator iPos( m_jar_typelibs.begin() );
     888           2 :         t_stringlist::const_iterator const iEnd( m_jar_typelibs.end() );
     889           2 :         buf.append( "UNO_JAVA_CLASSPATH=" );
     890           6 :         while (iPos != iEnd) {
     891             :             // encoded ASCII file-urls:
     892             :             const OString item(
     893           2 :                 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
     894           2 :             buf.append( item );
     895           2 :             ++iPos;
     896           2 :             if (iPos != iEnd)
     897           0 :                 buf.append( ' ' );
     898           2 :         }
     899           2 :         buf.append(LF);
     900             :     }
     901           6 :     if (! m_rdb_typelibs.empty())
     902             :     {
     903           0 :         t_stringlist::const_iterator iPos( m_rdb_typelibs.begin() );
     904           0 :         t_stringlist::const_iterator const iEnd( m_rdb_typelibs.end() );
     905           0 :         buf.append( "UNO_TYPES=" );
     906           0 :         while (iPos != iEnd) {
     907           0 :             buf.append( '?' );
     908             :             // encoded ASCII file-urls:
     909             :             const OString item(
     910           0 :                 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
     911           0 :             buf.append( item );
     912           0 :             ++iPos;
     913           0 :             if (iPos != iEnd)
     914           0 :                 buf.append( ' ' );
     915           0 :         }
     916           0 :         buf.append(LF);
     917             :     }
     918             : 
     919             :     // If we duplicated the common or native rdb then we must use those urls
     920             :     //otherwise we use those of the original files. That is, m_commonRDB_orig
     921             :     //and m_nativeRDB_orig;
     922          12 :     OUString sCommonRDB(m_commonRDB.isEmpty() ? m_commonRDB_orig : m_commonRDB );
     923          12 :     OUString sNativeRDB(m_nativeRDB.isEmpty() ? m_nativeRDB_orig : m_nativeRDB );
     924             : 
     925           6 :     if (!sCommonRDB.isEmpty() || !sNativeRDB.isEmpty() ||
     926           0 :         !m_components.empty())
     927             :     {
     928           6 :         buf.append( "UNO_SERVICES=" );
     929           6 :         bool space = false;
     930           6 :         if (!sCommonRDB.isEmpty())
     931             :         {
     932           6 :             buf.append( "?$ORIGIN/" );
     933             :             buf.append( OUStringToOString(
     934           6 :                             sCommonRDB, RTL_TEXTENCODING_ASCII_US ) );
     935           6 :             space = true;
     936             :         }
     937           6 :         if (!sNativeRDB.isEmpty())
     938             :         {
     939           6 :             if (space)
     940             :             {
     941           6 :                 buf.append(' ');
     942             :             }
     943           6 :             buf.append( "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}" );
     944           6 :             space = true;
     945             : 
     946             :             // write native rc:
     947           6 :             OStringBuffer buf2;
     948           6 :             buf2.append("ORIGIN=");
     949           6 :             buf2.append(osOrigin);
     950           6 :             buf2.append(LF);
     951           6 :             buf2.append( "UNO_SERVICES=?$ORIGIN/" );
     952             :             buf2.append( OUStringToOString(
     953           6 :                              sNativeRDB, RTL_TEXTENCODING_ASCII_US ) );
     954           6 :             buf2.append(LF);
     955             : 
     956             :             const Reference<io::XInputStream> xData(
     957             :                 ::xmlscript::createInputStream(
     958             :                     ::rtl::ByteSequence(
     959           6 :                         reinterpret_cast<sal_Int8 const *>(buf2.getStr()),
     960          18 :                         buf2.getLength() ) ) );
     961             :             ::ucbhelper::Content ucb_content(
     962          18 :                 makeURL( getCachePath(), getPlatformString() + "rc" ),
     963          24 :                 xCmdEnv, m_xComponentContext );
     964          12 :             ucb_content.writeStream( xData, true /* replace existing */ );
     965             :         }
     966          18 :         for (t_stringlist::iterator i(m_components.begin());
     967          12 :              i != m_components.end(); ++i)
     968             :         {
     969           0 :             if (space)
     970             :             {
     971           0 :                 buf.append(' ');
     972             :             }
     973           0 :             buf.append('?');
     974           0 :             buf.append(OUStringToOString(*i, RTL_TEXTENCODING_UTF8));
     975           0 :             space = true;
     976             :         }
     977           6 :         buf.append(LF);
     978             :     }
     979             : 
     980             :     // write unorc:
     981             :     const Reference<io::XInputStream> xData(
     982             :         ::xmlscript::createInputStream(
     983             :             ::rtl::ByteSequence(
     984           6 :                 reinterpret_cast<sal_Int8 const *>(buf.getStr()),
     985          18 :                 buf.getLength() ) ) );
     986             :     ::ucbhelper::Content ucb_content(
     987          12 :         makeURL( getCachePath(), "unorc" ), xCmdEnv, m_xComponentContext );
     988           6 :     ucb_content.writeStream( xData, true /* replace existing */ );
     989             : 
     990          12 :     m_unorc_modified = false;
     991             : }
     992             : 
     993             : 
     994           2 : bool BackendImpl::addToUnoRc( RcItem kind, OUString const & url_,
     995             :                               Reference<XCommandEnvironment> const & xCmdEnv )
     996             : {
     997           2 :     const OUString rcterm( dp_misc::makeRcTerm(url_) );
     998           4 :     const ::osl::MutexGuard guard( getMutex() );
     999           2 :     unorc_verify_init( xCmdEnv );
    1000           2 :     t_stringlist & rSet = getRcItemList(kind);
    1001           2 :     if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
    1002           2 :         rSet.push_front( rcterm ); // prepend to list, thus overriding
    1003             :         // write immediately:
    1004           2 :         m_unorc_modified = true;
    1005           2 :         unorc_flush( xCmdEnv );
    1006           2 :         return true;
    1007             :     }
    1008             :     else
    1009           2 :         return false;
    1010             : }
    1011             : 
    1012             : 
    1013           2 : bool BackendImpl::removeFromUnoRc(
    1014             :     RcItem kind, OUString const & url_,
    1015             :     Reference<XCommandEnvironment> const & xCmdEnv )
    1016             : {
    1017           2 :     const OUString rcterm( dp_misc::makeRcTerm(url_) );
    1018           4 :     const ::osl::MutexGuard guard( getMutex() );
    1019           2 :     unorc_verify_init( xCmdEnv );
    1020           2 :     getRcItemList(kind).remove( rcterm );
    1021             :     // write immediately:
    1022           2 :     m_unorc_modified = true;
    1023           2 :     unorc_flush( xCmdEnv );
    1024           4 :     return true;
    1025             : }
    1026             : 
    1027             : 
    1028           0 : bool BackendImpl::hasInUnoRc(
    1029             :     RcItem kind, OUString const & url_ )
    1030             : {
    1031           0 :     const OUString rcterm( dp_misc::makeRcTerm(url_) );
    1032           0 :     const ::osl::MutexGuard guard( getMutex() );
    1033           0 :     t_stringlist const & rSet = getRcItemList(kind);
    1034           0 :     return ::std::find( rSet.begin(), rSet.end(), rcterm ) != rSet.end();
    1035             : }
    1036             : 
    1037           4 : css::uno::Reference< css::uno::XComponentContext > BackendImpl::getRootContext()
    1038             :     const
    1039             : {
    1040             :     css::uno::Reference< css::uno::XComponentContext > rootContext(
    1041           4 :         getComponentContext()->getValueByName("_root"),
    1042           4 :         css::uno::UNO_QUERY);
    1043           4 :     return rootContext.is() ? rootContext : getComponentContext();
    1044             : }
    1045             : 
    1046             : 
    1047           2 : void BackendImpl::releaseObject( OUString const & id )
    1048             : {
    1049           2 :     const ::osl::MutexGuard guard( getMutex() );
    1050           2 :     m_backendObjects.erase( id );
    1051           2 : }
    1052             : 
    1053             : 
    1054           4 : Reference<XInterface> BackendImpl::getObject( OUString const & id )
    1055             : {
    1056           4 :     const ::osl::MutexGuard guard( getMutex() );
    1057           4 :     const t_string2object::const_iterator iFind( m_backendObjects.find( id ) );
    1058           4 :     if (iFind == m_backendObjects.end())
    1059           2 :         return Reference<XInterface>();
    1060             :     else
    1061           2 :         return iFind->second;
    1062             : }
    1063             : 
    1064             : 
    1065           2 : Reference<XInterface> BackendImpl::insertObject(
    1066             :     OUString const & id, Reference<XInterface> const & xObject )
    1067             : {
    1068           2 :     const ::osl::MutexGuard guard( getMutex() );
    1069             :     const ::std::pair<t_string2object::iterator, bool> insertion(
    1070             :         m_backendObjects.insert( t_string2object::value_type(
    1071           2 :                                      id, xObject ) ) );
    1072           2 :     return insertion.first->second;
    1073             : }
    1074             : 
    1075             : 
    1076           2 : Reference<XComponentContext> raise_uno_process(
    1077             :     Reference<XComponentContext> const & xContext,
    1078             :     ::rtl::Reference<AbortChannel> const & abortChannel )
    1079             : {
    1080             :     OSL_ASSERT( xContext.is() );
    1081             : 
    1082           2 :     OUString url( util::theMacroExpander::get(xContext)->expandMacros( "$URE_BIN_DIR/uno" ) );
    1083             : 
    1084           4 :     OUStringBuffer buf;
    1085           2 :     buf.appendAscii( "uno:pipe,name=" );
    1086           4 :     OUString pipeId( generateRandomPipeId() );
    1087           2 :     buf.append( pipeId );
    1088           2 :     buf.appendAscii( ";urp;uno.ComponentContext" );
    1089           4 :     const OUString connectStr( buf.makeStringAndClear() );
    1090             : 
    1091             :     // raise core UNO process to register/run a component,
    1092             :     // javavm service uses unorc next to executable to retrieve deployed
    1093             :     // jar typelibs
    1094             : 
    1095           4 :     ::std::vector<OUString> args;
    1096             : #if OSL_DEBUG_LEVEL == 0
    1097           2 :     args.push_back( "--quiet" );
    1098             : #endif
    1099           2 :     args.push_back( "--singleaccept" );
    1100           2 :     args.push_back( "-u" );
    1101           2 :     args.push_back( connectStr );
    1102             :     // don't inherit from unorc:
    1103           2 :     args.push_back( "-env:INIFILENAME=" );
    1104             : 
    1105             :     //now add the bootstrap variables which were supplied on the command line
    1106           4 :     ::std::vector<OUString> bootvars = getCmdBootstrapVariables();
    1107           2 :     args.insert(args.end(), bootvars.begin(), bootvars.end());
    1108             : 
    1109             :     oslProcess hProcess = raiseProcess(
    1110           2 :         url, comphelper::containerToSequence(args) );
    1111             :     try {
    1112             :         return Reference<XComponentContext>(
    1113             :             resolveUnoURL( connectStr, xContext, abortChannel.get() ),
    1114           4 :             UNO_QUERY_THROW );
    1115             :     }
    1116           0 :     catch (...) {
    1117             :         // try to terminate process:
    1118           0 :         if ( osl_terminateProcess( hProcess ) != osl_Process_E_None )
    1119             :         {
    1120             :             OSL_ASSERT( false );
    1121             :         }
    1122           0 :         throw;
    1123           2 :     }
    1124             : }
    1125             : 
    1126             : 
    1127             : namespace {
    1128             : 
    1129           2 : void extractComponentData(
    1130             :     css::uno::Reference< css::uno::XComponentContext > const & context,
    1131             :     css::uno::Reference< css::registry::XRegistryKey > const & registry,
    1132             :     ComponentBackendDb::Data * data,
    1133             :     std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
    1134             :     css::uno::Reference< css::loader::XImplementationLoader > const &
    1135             :         componentLoader,
    1136             :     OUString const & componentUrl)
    1137             : {
    1138             :     OSL_ASSERT(
    1139             :         context.is() && registry.is() && data != 0 && componentLoader.is());
    1140           2 :     OUString registryName(registry->getKeyName());
    1141           2 :     sal_Int32 prefix = registryName.getLength();
    1142           2 :     if (!registryName.endsWith("/")) {
    1143           0 :         prefix += RTL_CONSTASCII_LENGTH("/");
    1144             :     }
    1145             :     css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
    1146           4 :         keys(registry->openKeys());
    1147             :     css::uno::Reference< css::lang::XMultiComponentFactory > smgr(
    1148           4 :         context->getServiceManager(), css::uno::UNO_QUERY_THROW);
    1149           4 :     for (sal_Int32 i = 0; i < keys.getLength(); ++i) {
    1150           2 :         OUString name(keys[i]->getKeyName().copy(prefix));
    1151           2 :         data->implementationNames.push_back(name);
    1152             :         css::uno::Reference< css::registry::XRegistryKey > singletons(
    1153           4 :             keys[i]->openKey("UNO/SINGLETONS"));
    1154           2 :         if (singletons.is()) {
    1155           0 :             sal_Int32 prefix2 = keys[i]->getKeyName().getLength() +
    1156           0 :                 RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/");
    1157             :             css::uno::Sequence<
    1158             :                 css::uno::Reference< css::registry::XRegistryKey > >
    1159           0 :                 singletonKeys(singletons->openKeys());
    1160           0 :             for (sal_Int32 j = 0; j < singletonKeys.getLength(); ++j) {
    1161             :                 data->singletons.push_back(
    1162             :                     std::pair< OUString, OUString >(
    1163           0 :                         singletonKeys[j]->getKeyName().copy(prefix2), name));
    1164           0 :             }
    1165             :         }
    1166           2 :         if (factories != 0) {
    1167             :             factories->push_back(
    1168           2 :                 componentLoader->activate(
    1169           2 :                     name, OUString(), componentUrl, keys[i]));
    1170             :         }
    1171           4 :     }
    1172           2 : }
    1173             : 
    1174             : }
    1175             : 
    1176           2 : void BackendImpl::ComponentPackageImpl::getComponentInfo(
    1177             :     ComponentBackendDb::Data * data,
    1178             :     std::vector< css::uno::Reference< css::uno::XInterface > > * factories,
    1179             :     Reference<XComponentContext> const & xContext )
    1180             : {
    1181             :     const Reference<loader::XImplementationLoader> xLoader(
    1182           4 :         xContext->getServiceManager()->createInstanceWithContext(
    1183           2 :             m_loader, xContext ), UNO_QUERY );
    1184           2 :     if (! xLoader.is())
    1185             :     {
    1186             :         throw css::deployment::DeploymentException(
    1187           0 :             "cannot instantiate loader " + m_loader,
    1188           0 :             static_cast< OWeakObject * >(this), Any());
    1189             :     }
    1190             : 
    1191             :     // HACK: highly dependent on stoc/source/servicemanager
    1192             :     //       and stoc/source/implreg implementation which rely on the same
    1193             :     //       services.rdb format!
    1194             :     //       .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by
    1195             :     //       writeRegistryInfo, however, but are known, fixed values here, so
    1196             :     //       can be passed into extractComponentData
    1197           4 :     OUString url(getURL());
    1198             :     const Reference<registry::XSimpleRegistry> xMemReg(
    1199           4 :         xContext->getServiceManager()->createInstanceWithContext(
    1200           2 :             "com.sun.star.registry.SimpleRegistry", xContext ),
    1201           4 :         UNO_QUERY_THROW );
    1202           2 :     xMemReg->open( OUString() /* in mem */, false, true );
    1203           2 :     xLoader->writeRegistryInfo( xMemReg->getRootKey(), OUString(), url );
    1204             :     extractComponentData(
    1205           4 :         xContext, xMemReg->getRootKey(), data, factories, xLoader, url);
    1206           2 : }
    1207             : 
    1208           2 : void BackendImpl::ComponentPackageImpl::componentLiveInsertion(
    1209             :     ComponentBackendDb::Data const & data,
    1210             :     std::vector< css::uno::Reference< css::uno::XInterface > > const &
    1211             :         factories)
    1212             : {
    1213             :     css::uno::Reference< css::uno::XComponentContext > rootContext(
    1214           2 :         getMyBackend()->getRootContext());
    1215             :     css::uno::Reference< css::container::XSet > set(
    1216           4 :         rootContext->getServiceManager(), css::uno::UNO_QUERY_THROW);
    1217             :     std::vector< css::uno::Reference< css::uno::XInterface > >::const_iterator
    1218           2 :         factory(factories.begin());
    1219          12 :     for (t_stringlist::const_iterator i(data.implementationNames.begin());
    1220           8 :          i != data.implementationNames.end(); ++i)
    1221             :     {
    1222             :         try {
    1223           2 :             set->insert(css::uno::Any(*factory++));
    1224           0 :         } catch (const container::ElementExistException &) {
    1225             :             OSL_TRACE(
    1226             :                 "implementation %s already registered",
    1227             :                 OUStringToOString(*i, RTL_TEXTENCODING_UTF8).getStr());
    1228             :         }
    1229             :     }
    1230           2 :     if (!data.singletons.empty()) {
    1231             :         css::uno::Reference< css::container::XNameContainer > cont(
    1232           0 :             rootContext, css::uno::UNO_QUERY_THROW);
    1233           0 :         for (t_stringpairvec::const_iterator i(data.singletons.begin());
    1234           0 :              i != data.singletons.end(); ++i)
    1235             :         {
    1236           0 :             OUString name("/singletons/" + i->first);
    1237             :             //TODO: Update should be atomic:
    1238             :             try {
    1239           0 :                 cont->removeByName( name + "/arguments");
    1240           0 :             } catch (const container::NoSuchElementException &) {}
    1241             :             try {
    1242           0 :                 cont->insertByName( name + "/service", css::uno::Any(i->second));
    1243           0 :             } catch (const container::ElementExistException &) {
    1244           0 :                 cont->replaceByName( name + "/service", css::uno::Any(i->second));
    1245             :             }
    1246             :             try {
    1247           0 :                 cont->insertByName(name, css::uno::Any());
    1248           0 :             } catch (const container::ElementExistException &) {
    1249             :                 OSL_TRACE(
    1250             :                     "singleton %s already registered",
    1251             :                     OUStringToOString(
    1252             :                         i->first, RTL_TEXTENCODING_UTF8).getStr());
    1253           0 :                 cont->replaceByName(name, css::uno::Any());
    1254             :             }
    1255           0 :         }
    1256           2 :     }
    1257           2 : }
    1258             : 
    1259           2 : void BackendImpl::ComponentPackageImpl::componentLiveRemoval(
    1260             :     ComponentBackendDb::Data const & data)
    1261             : {
    1262             :     css::uno::Reference< css::uno::XComponentContext > rootContext(
    1263           2 :         getMyBackend()->getRootContext());
    1264             :     css::uno::Reference< css::container::XSet > set(
    1265           4 :         rootContext->getServiceManager(), css::uno::UNO_QUERY_THROW);
    1266          12 :     for (t_stringlist::const_iterator i(data.implementationNames.begin());
    1267           8 :          i != data.implementationNames.end(); ++i)
    1268             :     {
    1269             :         try {
    1270           2 :             set->remove(css::uno::Any(*i));
    1271           0 :         } catch (const css::container::NoSuchElementException &) {
    1272             :             // ignore if factory has not been live deployed
    1273             :         }
    1274             :     }
    1275           2 :     if (!data.singletons.empty()) {
    1276             :         css::uno::Reference< css::container::XNameContainer > cont(
    1277           0 :             rootContext, css::uno::UNO_QUERY_THROW);
    1278           0 :         for (t_stringpairvec::const_iterator i(data.singletons.begin());
    1279           0 :              i != data.singletons.end(); ++i)
    1280             :         {
    1281           0 :             OUString name("/singletons/" + i->first);
    1282             :             //TODO: Removal should be atomic:
    1283             :             try {
    1284           0 :                 cont->removeByName(name);
    1285           0 :             } catch (const container::NoSuchElementException &) {}
    1286             :             try {
    1287           0 :                 cont->removeByName( name + "/service" );
    1288           0 :             } catch (const container::NoSuchElementException &) {}
    1289             :             try {
    1290           0 :                 cont->removeByName( name + "/arguments" );
    1291           0 :             } catch (const container::NoSuchElementException &) {}
    1292           0 :         }
    1293           2 :     }
    1294           2 : }
    1295             : 
    1296             : // Package
    1297             : 
    1298             : //We could use here BackendImpl::hasActiveEntry. However, this check is just as well.
    1299             : //And it also shows the problem if another extension has overwritten an implementation
    1300             : //entry, because it contains the same service implementation
    1301             : beans::Optional< beans::Ambiguous<sal_Bool> >
    1302          12 : BackendImpl::ComponentPackageImpl::isRegistered_(
    1303             :     ::osl::ResettableMutexGuard &,
    1304             :     ::rtl::Reference<AbortChannel> const & abortChannel,
    1305             :     Reference<XCommandEnvironment> const & )
    1306             : {
    1307          12 :     if (m_registered == REG_UNINIT)
    1308             :     {
    1309           2 :         m_registered = REG_NOT_REGISTERED;
    1310           2 :         bool bAmbiguousComponentName = false;
    1311           2 :         const Reference<registry::XSimpleRegistry> xRDB( getRDB() );
    1312           2 :         if (xRDB.is())
    1313             :         {
    1314             :             // lookup rdb for location URL:
    1315             :             const Reference<registry::XRegistryKey> xRootKey(
    1316           2 :                 xRDB->getRootKey() );
    1317             :             const Reference<registry::XRegistryKey> xImplKey(
    1318           4 :                 xRootKey->openKey( "IMPLEMENTATIONS" ) );
    1319           4 :             Sequence<OUString> implNames;
    1320           2 :             if (xImplKey.is() && xImplKey->isValid())
    1321           0 :                 implNames = xImplKey->getKeyNames();
    1322           2 :             OUString const * pImplNames = implNames.getConstArray();
    1323           2 :             sal_Int32 pos = implNames.getLength();
    1324           2 :             for ( ; pos--; )
    1325             :             {
    1326           0 :                 checkAborted( abortChannel );
    1327             :                 const OUString key(
    1328           0 :                     pImplNames[ pos ] + "/UNO/LOCATION" );
    1329             :                 const Reference<registry::XRegistryKey> xKey(
    1330           0 :                     xRootKey->openKey(key) );
    1331           0 :                 if (xKey.is() && xKey->isValid())
    1332             :                 {
    1333           0 :                     const OUString location( xKey->getAsciiValue() );
    1334           0 :                     if (location.equalsIgnoreAsciiCase( getURL() ))
    1335             :                     {
    1336           0 :                         break;
    1337             :                     }
    1338             :                     else
    1339             :                     {
    1340             :                         //try to match only the file name
    1341           0 :                         OUString thisUrl(getURL());
    1342           0 :                         OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/')));
    1343             : 
    1344           0 :                         OUString locationFileName(location.copy(location.lastIndexOf('/')));
    1345           0 :                         if (locationFileName.equalsIgnoreAsciiCase(thisFileName))
    1346           0 :                             bAmbiguousComponentName = true;
    1347           0 :                     }
    1348             :                 }
    1349           0 :             }
    1350           2 :             if (pos >= 0)
    1351           0 :                 m_registered = REG_REGISTERED;
    1352           2 :             else if (bAmbiguousComponentName)
    1353           2 :                 m_registered = REG_MAYBE_REGISTERED;
    1354           2 :         }
    1355             :     }
    1356             : 
    1357             :     //Different extensions can use the same service implementations. Then the extensions
    1358             :     //which was installed last will overwrite the one from the other extension. That is
    1359             :     //the registry will contain the path (the location) of the library or jar of the
    1360             :     //second extension. In this case isRegistered called for the lib of the first extension
    1361             :     //would return "not registered". That would mean that during uninstallation
    1362             :     //XPackage::registerPackage is not called, because it just was not registered. This is,
    1363             :     //however, necessary for jar files. Registering and unregistering update
    1364             :     //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
    1365             :     //Therefore, we will return always "is ambiguous" if the path of this component cannot
    1366             :     //be found in the registry and if there is another path and both have the same file name (but
    1367             :     //the rest of the path is different).
    1368             :     //If the caller cannot precisely determine that this package was registered, then it must
    1369             :     //call registerPackage.
    1370          12 :     bool bAmbiguous = m_registered == REG_VOID // REG_VOID == we are in the progress of unregistration
    1371          12 :         || m_registered == REG_MAYBE_REGISTERED;
    1372             :     return beans::Optional< beans::Ambiguous<sal_Bool> >(
    1373             :         true /* IsPresent */,
    1374             :         beans::Ambiguous<sal_Bool>(
    1375          12 :             m_registered == REG_REGISTERED, bAmbiguous) );
    1376             : }
    1377             : 
    1378             : 
    1379           4 : void BackendImpl::ComponentPackageImpl::processPackage_(
    1380             :     ::osl::ResettableMutexGuard &,
    1381             :     bool doRegisterPackage,
    1382             :     bool startup,
    1383             :     ::rtl::Reference<AbortChannel> const & abortChannel,
    1384             :     Reference<XCommandEnvironment> const & xCmdEnv )
    1385             : {
    1386           4 :     BackendImpl * that = getMyBackend();
    1387           4 :     OUString url(getURL());
    1388           4 :     if (doRegisterPackage) {
    1389           2 :         ComponentBackendDb::Data data;
    1390           4 :         css::uno::Reference< css::uno::XComponentContext > context;
    1391           2 :         if (startup) {
    1392           0 :             context = that->getComponentContext();
    1393             :         } else {
    1394           2 :             context.set(that->getObject(url), css::uno::UNO_QUERY);
    1395           2 :             if (!context.is()) {
    1396             :                 context.set(
    1397             :                     that->insertObject(
    1398             :                         url,
    1399             :                         raise_uno_process(
    1400           4 :                             that->getComponentContext(), abortChannel)),
    1401           2 :                     css::uno::UNO_QUERY_THROW);
    1402             :             }
    1403             :         }
    1404             :         css::uno::Reference< css::registry::XImplementationRegistration> impreg(
    1405           4 :             context->getServiceManager()->createInstanceWithContext(
    1406             :                 "com.sun.star.registry.ImplementationRegistration",
    1407           2 :                 context),
    1408           4 :             css::uno::UNO_QUERY_THROW);
    1409           4 :         css::uno::Reference< css::registry::XSimpleRegistry > rdb(getRDB());
    1410           2 :         impreg->registerImplementation(m_loader, url, rdb);
    1411             :         // Only write to unorc after successful registration; it may fail if
    1412             :         // there is no suitable java
    1413           2 :         if (m_loader == "com.sun.star.loader.Java2" && !jarManifestHeaderPresent(url, "UNO-Type-Path", xCmdEnv))
    1414             :         {
    1415           2 :             that->addToUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
    1416           2 :             data.javaTypeLibrary = true;
    1417             :         }
    1418           4 :         std::vector< css::uno::Reference< css::uno::XInterface > > factories;
    1419           2 :         getComponentInfo(&data, startup ? 0 : &factories, context);
    1420           2 :         if (!startup) {
    1421             :             try {
    1422           2 :                 componentLiveInsertion(data, factories);
    1423           0 :             } catch (css::uno::Exception & e) {
    1424             :                 SAL_INFO(
    1425             :                     "desktop.deployment", "caught Exception " << e.Message);
    1426             :                 try {
    1427           0 :                     impreg->revokeImplementation(url, rdb);
    1428           0 :                 } catch (css::uno::RuntimeException & e2) {
    1429             :                     SAL_WARN(
    1430             :                         "desktop.deployment",
    1431             :                         "ignored RuntimeException " << e2.Message);
    1432             :                 }
    1433           0 :                 throw;
    1434             :             }
    1435             :         }
    1436           2 :         m_registered = REG_REGISTERED;
    1437           4 :         that->addDataToDb(url, data);
    1438             :     } else { // revoke
    1439           2 :         m_registered = REG_VOID;
    1440           2 :         ComponentBackendDb::Data data(that->readDataFromDb(url));
    1441             :         css::uno::Reference< css::uno::XComponentContext > context(
    1442           4 :             that->getObject(url), css::uno::UNO_QUERY);
    1443           2 :         bool remoteContext = context.is();
    1444           2 :         if (!remoteContext) {
    1445           0 :             context = that->getComponentContext();
    1446             :         }
    1447           2 :         if (!startup) {
    1448           2 :             componentLiveRemoval(data);
    1449             :         }
    1450             :         css::uno::Reference< css::registry::XImplementationRegistration >(
    1451           4 :             context->getServiceManager()->createInstanceWithContext(
    1452             :                 "com.sun.star.registry.ImplementationRegistration",
    1453           2 :                 context),
    1454           2 :             css::uno::UNO_QUERY_THROW)->revokeImplementation(url, getRDB());
    1455           2 :         if (data.javaTypeLibrary) {
    1456           2 :             that->removeFromUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv);
    1457             :         }
    1458           2 :         if (remoteContext) {
    1459           2 :             that->releaseObject(url);
    1460             :         }
    1461           2 :         m_registered = REG_NOT_REGISTERED;
    1462           4 :         getMyBackend()->revokeEntryFromDb(url);
    1463           4 :     }
    1464           4 : }
    1465             : 
    1466           0 : BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl(
    1467             :     ::rtl::Reference<PackageRegistryBackend> const & myBackend,
    1468             :     OUString const & url, OUString const & name,
    1469             :     Reference<deployment::XPackageTypeInfo> const & xPackageType,
    1470             :     bool jarFile, bool bRemoved, OUString const & identifier)
    1471             :     : Package( myBackend, url, name, name /* display-name */,
    1472             :                xPackageType, bRemoved, identifier),
    1473           0 :       m_jarFile( jarFile )
    1474             : {
    1475           0 : }
    1476             : 
    1477             : // Package
    1478           0 : BackendImpl * BackendImpl::TypelibraryPackageImpl::getMyBackend() const
    1479             : {
    1480           0 :     BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
    1481           0 :     if (NULL == pBackend)
    1482             :     {
    1483             :         //May throw a DisposedException
    1484           0 :         check();
    1485             :         //We should never get here...
    1486             :         throw RuntimeException( "Failed to get the BackendImpl",
    1487           0 :             static_cast<OWeakObject*>(const_cast<TypelibraryPackageImpl *>(this)));
    1488             :     }
    1489           0 :     return pBackend;
    1490             : }
    1491             : 
    1492             : beans::Optional< beans::Ambiguous<sal_Bool> >
    1493           0 : BackendImpl::TypelibraryPackageImpl::isRegistered_(
    1494             :     ::osl::ResettableMutexGuard &,
    1495             :     ::rtl::Reference<AbortChannel> const &,
    1496             :     Reference<XCommandEnvironment> const & )
    1497             : {
    1498           0 :     BackendImpl * that = getMyBackend();
    1499             :     return beans::Optional< beans::Ambiguous<sal_Bool> >(
    1500             :         true /* IsPresent */,
    1501             :         beans::Ambiguous<sal_Bool>(
    1502             :             that->hasInUnoRc(
    1503           0 :                 m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, getURL() ),
    1504           0 :             false /* IsAmbiguous */ ) );
    1505             : }
    1506             : 
    1507             : 
    1508           0 : void BackendImpl::TypelibraryPackageImpl::processPackage_(
    1509             :     ::osl::ResettableMutexGuard &,
    1510             :     bool doRegisterPackage,
    1511             :     bool /*startup*/,
    1512             :     ::rtl::Reference<AbortChannel> const &,
    1513             :     Reference<XCommandEnvironment> const & xCmdEnv )
    1514             : {
    1515           0 :     BackendImpl * that = getMyBackend();
    1516           0 :     const OUString url( getURL() );
    1517             : 
    1518           0 :     if (doRegisterPackage)
    1519             :     {
    1520             :         // live insertion:
    1521           0 :         if (m_jarFile) {
    1522             :             // xxx todo add to classpath at runtime: ???
    1523             :             //SB: It is probably not worth it to add the live inserted type
    1524             :             // library JAR to the UnoClassLoader in the soffice process.  Any
    1525             :             // live inserted component JAR that might reference this type
    1526             :             // library JAR runs in its own uno process, so there is probably no
    1527             :             // Java code in the soffice process that would see any UNO types
    1528             :             // introduced by this type library JAR.
    1529             :         }
    1530             :         else // RDB:
    1531             :         {
    1532             :             css::uno::Reference< css::container::XSet >(
    1533           0 :                 that->getComponentContext()->getValueByName(
    1534             :                     "/singletons"
    1535           0 :                     "/com.sun.star.reflection.theTypeDescriptionManager"),
    1536           0 :                 css::uno::UNO_QUERY_THROW)->insert(
    1537           0 :                     css::uno::makeAny(expandUnoRcUrl(url)));
    1538             :         }
    1539             : 
    1540             :         that->addToUnoRc( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB,
    1541           0 :                           url, xCmdEnv );
    1542             :     }
    1543             :     else // revokePackage()
    1544             :     {
    1545             :         that->removeFromUnoRc(
    1546           0 :             m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, url, xCmdEnv );
    1547             : 
    1548             :         // revoking types at runtime, possible, sensible?
    1549           0 :         if (!m_jarFile) {
    1550             :             css::uno::Reference< css::container::XSet >(
    1551           0 :                 that->getComponentContext()->getValueByName(
    1552             :                     "/singletons"
    1553           0 :                     "/com.sun.star.reflection.theTypeDescriptionManager"),
    1554           0 :                 css::uno::UNO_QUERY_THROW)->remove(
    1555           0 :                     css::uno::makeAny(expandUnoRcUrl(url)));
    1556             :         }
    1557           0 :     }
    1558           0 : }
    1559             : 
    1560           0 : BackendImpl::OtherPlatformPackageImpl::OtherPlatformPackageImpl(
    1561             :     ::rtl::Reference<PackageRegistryBackend> const & myBackend,
    1562             :     OUString const & url, OUString const & name,
    1563             :     Reference<deployment::XPackageTypeInfo> const & xPackageType,
    1564             :     bool bRemoved, OUString const & identifier, OUString const& rPlatform)
    1565             :     : Package(myBackend, url, name, name, xPackageType, bRemoved, identifier)
    1566           0 :     , m_aPlatform(rPlatform)
    1567             : {
    1568             :     OSL_PRECOND(bRemoved, "this class can only be used for removing packages!");
    1569           0 : }
    1570             : 
    1571             : BackendImpl *
    1572           0 : BackendImpl::OtherPlatformPackageImpl::getMyBackend() const
    1573             : {
    1574           0 :     BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
    1575           0 :     if (NULL == pBackend)
    1576             :     {
    1577             :         //Throws a DisposedException
    1578           0 :         check();
    1579             :         //We should never get here...
    1580             :         throw RuntimeException("Failed to get the BackendImpl",
    1581           0 :             static_cast<OWeakObject*>(const_cast<OtherPlatformPackageImpl*>(this)));
    1582             :     }
    1583           0 :     return pBackend;
    1584             : }
    1585             : 
    1586             : Reference<registry::XSimpleRegistry> const
    1587           0 : BackendImpl::OtherPlatformPackageImpl::impl_openRDB() const
    1588             : {
    1589           0 :     OUString const aRDB(m_aPlatform + ".rdb");
    1590           0 :     OUString const aRDBPath(makeURL(getMyBackend()->getCachePath(), aRDB));
    1591             : 
    1592           0 :     Reference<registry::XSimpleRegistry> xRegistry;
    1593             : 
    1594             :     try
    1595             :     {
    1596             :         xRegistry.set(
    1597             :                 impl_createInstance("com.sun.star.registry.SimpleRegistry"),
    1598           0 :                 UNO_QUERY)
    1599           0 :             ;
    1600           0 :         if (xRegistry.is())
    1601           0 :             xRegistry->open(expandUnoRcUrl(aRDBPath), false, false);
    1602             :     }
    1603           0 :     catch (registry::InvalidRegistryException const&)
    1604             :     {
    1605             :         // If the registry does not exist, we do not need to bother at all
    1606           0 :         xRegistry.set(0);
    1607             :     }
    1608             : 
    1609             :     SAL_WARN_IF( !xRegistry.is(), "desktop.deployment", "could not create registry for the package's platform");
    1610           0 :     return xRegistry;
    1611             : }
    1612             : 
    1613             : Reference<XInterface> const
    1614           0 : BackendImpl::OtherPlatformPackageImpl::impl_createInstance(OUString const& rService)
    1615             : const
    1616             : {
    1617           0 :     Reference<XComponentContext> const xContext(getMyBackend()->getComponentContext());
    1618             :     OSL_ASSERT(xContext.is());
    1619           0 :     Reference<XInterface> xService;
    1620           0 :     if (xContext.is())
    1621           0 :         xService.set(xContext->getServiceManager()->createInstanceWithContext(rService, xContext));
    1622           0 :     return xService;
    1623             : }
    1624             : 
    1625             : beans::Optional<beans::Ambiguous<sal_Bool> >
    1626           0 : BackendImpl::OtherPlatformPackageImpl::isRegistered_(
    1627             :     ::osl::ResettableMutexGuard& /* guard */,
    1628             :     ::rtl::Reference<AbortChannel> const& /* abortChannel */,
    1629             :     Reference<XCommandEnvironment> const& /* xCmdEnv */ )
    1630             : {
    1631             :     return beans::Optional<beans::Ambiguous<sal_Bool> >(sal_True,
    1632           0 :             beans::Ambiguous<sal_Bool>(sal_True, sal_False));
    1633             : }
    1634             : 
    1635             : void
    1636           0 : BackendImpl::OtherPlatformPackageImpl::processPackage_(
    1637             :     ::osl::ResettableMutexGuard& /* guard */,
    1638             :     bool bRegisterPackage,
    1639             :     bool /* bStartup */,
    1640             :     ::rtl::Reference<AbortChannel> const& /* abortChannel */,
    1641             :     Reference<XCommandEnvironment> const& /* xCmdEnv */)
    1642             : {
    1643             :     OSL_PRECOND(!bRegisterPackage, "this class can only be used for removing packages!");
    1644             :     (void) bRegisterPackage;
    1645             : 
    1646           0 :     OUString const aURL(getURL());
    1647             : 
    1648           0 :     Reference<registry::XSimpleRegistry> const xServicesRDB(impl_openRDB());
    1649             :     Reference<registry::XImplementationRegistration> const xImplReg(
    1650             :             impl_createInstance("com.sun.star.registry.ImplementationRegistration"),
    1651           0 :             UNO_QUERY)
    1652             :         ;
    1653           0 :     if (xImplReg.is() && xServicesRDB.is())
    1654           0 :         xImplReg->revokeImplementation(aURL, xServicesRDB);
    1655           0 :     if (xServicesRDB.is())
    1656           0 :         xServicesRDB->close();
    1657             : 
    1658           0 :     getMyBackend()->revokeEntryFromDb(aURL);
    1659           0 : }
    1660             : 
    1661           0 : BackendImpl * BackendImpl::ComponentsPackageImpl::getMyBackend() const
    1662             : {
    1663           0 :     BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
    1664           0 :     if (NULL == pBackend)
    1665             :     {
    1666             :         //Throws a DisposedException
    1667           0 :         check();
    1668             :         //We should never get here...
    1669             :         throw RuntimeException("Failed to get the BackendImpl",
    1670           0 :             static_cast<OWeakObject*>(const_cast<ComponentsPackageImpl *>(this)));
    1671             :     }
    1672           0 :     return pBackend;
    1673             : }
    1674             : 
    1675             : beans::Optional< beans::Ambiguous<sal_Bool> >
    1676           0 : BackendImpl::ComponentsPackageImpl::isRegistered_(
    1677             :     ::osl::ResettableMutexGuard &,
    1678             :     ::rtl::Reference<AbortChannel> const &,
    1679             :     Reference<XCommandEnvironment> const & )
    1680             : {
    1681             :     return beans::Optional< beans::Ambiguous<sal_Bool> >(
    1682             :         true,
    1683             :         beans::Ambiguous<sal_Bool>(
    1684           0 :             getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS, getURL()), false));
    1685             : }
    1686             : 
    1687           0 : void BackendImpl::ComponentsPackageImpl::processPackage_(
    1688             :     ::osl::ResettableMutexGuard &,
    1689             :     bool doRegisterPackage,
    1690             :     bool startup,
    1691             :     ::rtl::Reference<AbortChannel> const & abortChannel,
    1692             :     Reference<XCommandEnvironment> const & xCmdEnv )
    1693             : {
    1694           0 :     BackendImpl * that = getMyBackend();
    1695           0 :     OUString url(getURL());
    1696           0 :     if (doRegisterPackage) {
    1697           0 :         if (!startup) {
    1698             :             css::uno::Reference< css::uno::XComponentContext > context(
    1699           0 :                 that->getObject(url), css::uno::UNO_QUERY);
    1700           0 :             if (!context.is()) {
    1701             :                 context.set(
    1702             :                     that->insertObject(
    1703             :                         url,
    1704             :                         raise_uno_process(
    1705           0 :                             that->getComponentContext(), abortChannel)),
    1706           0 :                     css::uno::UNO_QUERY_THROW);
    1707             :             }
    1708             :             // This relies on the root component context's service manager
    1709             :             // supporting the extended XSet semantics:
    1710           0 :             css::uno::Sequence< css::beans::NamedValue > args(2);
    1711           0 :             args[0].Name = "uri";
    1712           0 :             args[0].Value <<= expandUnoRcUrl(url);
    1713           0 :             args[1].Name = "component-context";
    1714           0 :             args[1].Value <<= context;
    1715             :             css::uno::Reference< css::container::XSet > smgr(
    1716           0 :                 that->getRootContext()->getServiceManager(),
    1717           0 :                 css::uno::UNO_QUERY_THROW);
    1718           0 :             smgr->insert(css::uno::makeAny(args));
    1719             :         }
    1720           0 :         that->addToUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
    1721             :     } else { // revoke
    1722           0 :         that->removeFromUnoRc(RCITEM_COMPONENTS, url, xCmdEnv);
    1723           0 :         if (!startup) {
    1724             :             // This relies on the root component context's service manager
    1725             :             // supporting the extended XSet semantics:
    1726           0 :             css::uno::Sequence< css::beans::NamedValue > args(1);
    1727           0 :             args[0].Name = "uri";
    1728           0 :             args[0].Value <<= expandUnoRcUrl(url);
    1729             :             css::uno::Reference< css::container::XSet > smgr(
    1730           0 :                 that->getRootContext()->getServiceManager(),
    1731           0 :                 css::uno::UNO_QUERY_THROW);
    1732           0 :             smgr->remove(css::uno::makeAny(args));
    1733             :         }
    1734           0 :         that->releaseObject(url);
    1735           0 :         that->revokeEntryFromDb(url); // in case it got added with old code
    1736           0 :     }
    1737           0 : }
    1738             : 
    1739           0 : BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl(
    1740             :     ::rtl::Reference<PackageRegistryBackend> const & myBackend,
    1741             :     OUString const & url, OUString const & name,
    1742             :     Reference<deployment::XPackageTypeInfo> const & xPackageType,
    1743             :     bool bRemoved, OUString const & identifier)
    1744             :     : Package( myBackend, url, name, name /* display-name */,
    1745           0 :                xPackageType, bRemoved, identifier)
    1746           0 : {}
    1747             : 
    1748             : } // anon namespace
    1749             : 
    1750             : namespace sdecl = comphelper::service_decl;
    1751         140 : sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
    1752         140 : extern sdecl::ServiceDecl const serviceDecl(
    1753             :     serviceBI,
    1754             :     IMPLEMENTATION_NAME,
    1755             :     BACKEND_SERVICE_NAME );
    1756             : 
    1757             : } // namespace component
    1758             : } // namespace backend
    1759         420 : } // namespace dp_registry
    1760             : 
    1761             : 
    1762             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10