LCOV - code coverage report
Current view: top level - libreoffice/desktop/source/deployment/registry/component - dp_component.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 3 733 0.4 %
Date: 2012-12-27 Functions: 2 59 3.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10