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

Generated by: LCOV version 1.11