LCOV - code coverage report
Current view: top level - desktop/source/deployment/registry/configuration - dp_configuration.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 46 349 13.2 %
Date: 2014-04-11 Functions: 8 27 29.6 %
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             : //TODO: Large parts of this file were copied from dp_component.cxx; those parts
      21             : // should be consolidated.
      22             : 
      23             : #include <config_features.h>
      24             : 
      25             : #include "dp_configuration.hrc"
      26             : #include "dp_backend.h"
      27             : #if HAVE_FEATURE_EXTENSIONS
      28             : #include "dp_persmap.h"
      29             : #endif
      30             : #include "dp_ucb.h"
      31             : #include "rtl/string.hxx"
      32             : #include "rtl/ustrbuf.hxx"
      33             : #include "rtl/uri.hxx"
      34             : #include "osl/file.hxx"
      35             : #include "cppuhelper/exc_hlp.hxx"
      36             : #include "ucbhelper/content.hxx"
      37             : #include "unotools/ucbhelper.hxx"
      38             : #include "comphelper/anytostring.hxx"
      39             : #include "comphelper/servicedecl.hxx"
      40             : #include "xmlscript/xml_helper.hxx"
      41             : #include "svl/inettype.hxx"
      42             : #include "com/sun/star/configuration/Update.hpp"
      43             : #include "com/sun/star/ucb/NameClash.hpp"
      44             : #include "com/sun/star/io/XActiveDataSink.hpp"
      45             : #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
      46             : #include "com/sun/star/util/XRefreshable.hpp"
      47             : #include <list>
      48             : #include <memory>
      49             : 
      50             : #include "dp_configurationbackenddb.hxx"
      51             : 
      52             : using namespace ::dp_misc;
      53             : using namespace ::com::sun::star;
      54             : using namespace ::com::sun::star::uno;
      55             : using namespace ::com::sun::star::ucb;
      56             : 
      57             : namespace dp_registry {
      58             : namespace backend {
      59             : namespace configuration {
      60             : namespace {
      61             : 
      62             : typedef ::std::list<OUString> t_stringlist;
      63             : 
      64             : 
      65         245 : class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
      66             : {
      67           0 :     class PackageImpl : public ::dp_registry::backend::Package
      68             :     {
      69             :         BackendImpl * getMyBackend() const ;
      70             : 
      71             :         const bool m_isSchema;
      72             : 
      73             :         // Package
      74             :         virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
      75             :             ::osl::ResettableMutexGuard & guard,
      76             :             ::rtl::Reference<AbortChannel> const & abortChannel,
      77             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
      78             :         virtual void processPackage_(
      79             :             ::osl::ResettableMutexGuard & guard,
      80             :             bool registerPackage,
      81             :             bool startup,
      82             :             ::rtl::Reference<AbortChannel> const & abortChannel,
      83             :             Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
      84             : 
      85             :     public:
      86           0 :         inline PackageImpl(
      87             :             ::rtl::Reference<PackageRegistryBackend> const & myBackend,
      88             :             OUString const & url, OUString const & name,
      89             :             Reference<deployment::XPackageTypeInfo> const & xPackageType,
      90             :             bool isSchema, bool bRemoved, OUString const & identifier)
      91             :             : Package( myBackend, url, name, name /* display-name */,
      92             :                        xPackageType, bRemoved, identifier),
      93           0 :               m_isSchema( isSchema )
      94           0 :             {}
      95             :     };
      96             :     friend class PackageImpl;
      97             : 
      98             :     t_stringlist m_xcs_files;
      99             :     t_stringlist m_xcu_files;
     100           0 :     t_stringlist & getFiles( bool xcs ) {
     101           0 :         return xcs ? m_xcs_files : m_xcu_files;
     102             :     }
     103             : 
     104             :     bool m_configmgrini_inited;
     105             :     bool m_configmgrini_modified;
     106             :     std::auto_ptr<ConfigurationBackendDb> m_backendDb;
     107             : 
     108             :     // PackageRegistryBackend
     109             :     virtual Reference<deployment::XPackage> bindPackage_(
     110             :         OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
     111             :         OUString const & identifier,
     112             :         Reference<XCommandEnvironment> const & xCmdEnv ) SAL_OVERRIDE;
     113             : 
     114             : #if HAVE_FEATURE_EXTENSIONS
     115             :     // for backwards compatibility - nil if no (compatible) back-compat db present
     116             :     ::std::auto_ptr<PersistentMap> m_registeredPackages;
     117             : #endif
     118             : 
     119             :     virtual void SAL_CALL disposing() SAL_OVERRIDE;
     120             : 
     121             :     const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
     122             :     const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
     123             :     Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
     124             : 
     125             :     void configmgrini_verify_init(
     126             :         Reference<XCommandEnvironment> const & xCmdEnv );
     127             :     void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );
     128             : 
     129             :     /* The paramter isURL is false in the case of adding the conf:ini-entry
     130             :        value from the backend db. This entry already contains the path as it
     131             :        is used in the configmgr.ini.
     132             :      */
     133             :     bool addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url,
     134             :                      Reference<XCommandEnvironment> const & xCmdEnv );
     135             :     bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
     136             :                           Reference<XCommandEnvironment> const & xCmdEnv );
     137             : 
     138             :     void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
     139             :     ::boost::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
     140             :     void revokeEntryFromDb(OUString const & url);
     141             :     bool hasActiveEntry(OUString const & url);
     142             :     bool activateEntry(OUString const & url);
     143             : 
     144             : public:
     145             :     BackendImpl( Sequence<Any> const & args,
     146             :                  Reference<XComponentContext> const & xComponentContext );
     147             : 
     148             :     // XPackageRegistry
     149             :     virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
     150             :     getSupportedPackageTypes() throw (RuntimeException, std::exception) SAL_OVERRIDE;
     151             :     virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
     152             :         throw (deployment::DeploymentException,
     153             :                uno::RuntimeException, std::exception) SAL_OVERRIDE;
     154             : 
     155             :     using PackageRegistryBackend::disposing;
     156             : };
     157             : 
     158             : 
     159         245 : void BackendImpl::disposing()
     160             : {
     161             :     try {
     162         245 :         configmgrini_flush( Reference<XCommandEnvironment>() );
     163             : 
     164         245 :         PackageRegistryBackend::disposing();
     165             :     }
     166           0 :     catch (const RuntimeException &) {
     167           0 :         throw;
     168             :     }
     169           0 :     catch (const Exception &) {
     170           0 :         Any exc( ::cppu::getCaughtException() );
     171             :         throw lang::WrappedTargetRuntimeException(
     172             :             "caught unexpected exception while disposing...",
     173           0 :             static_cast<OWeakObject *>(this), exc );
     174             :     }
     175         245 : }
     176             : 
     177             : 
     178         245 : BackendImpl::BackendImpl(
     179             :     Sequence<Any> const & args,
     180             :     Reference<XComponentContext> const & xComponentContext )
     181             :     : PackageRegistryBackend( args, xComponentContext ),
     182             :       m_configmgrini_inited( false ),
     183             :       m_configmgrini_modified( false ),
     184             :       m_xConfDataTypeInfo( new Package::TypeInfo(
     185             :                                "application/vnd.sun.star.configuration-data",
     186             :                                "*.xcu",
     187             :                                getResourceString(RID_STR_CONF_DATA),
     188         245 :                                RID_IMG_CONF_XML ) ),
     189             :       m_xConfSchemaTypeInfo( new Package::TypeInfo(
     190             :                                  "application/vnd.sun.star.configuration-schema",
     191             :                                  "*.xcs",
     192             :                                  getResourceString(RID_STR_CONF_SCHEMA),
     193         245 :                                  RID_IMG_CONF_XML ) ),
     194         735 :       m_typeInfos( 2 )
     195             : {
     196         245 :     m_typeInfos[ 0 ] = m_xConfDataTypeInfo;
     197         245 :     m_typeInfos[ 1 ] = m_xConfSchemaTypeInfo;
     198             : 
     199         245 :     const Reference<XCommandEnvironment> xCmdEnv;
     200             : 
     201         245 :     if (transientMode())
     202             :     {
     203             :         // TODO
     204             :     }
     205             :     else
     206             :     {
     207         245 :         OUString dbFile = makeURL(getCachePath(), "backenddb.xml");
     208             :         m_backendDb.reset(
     209         245 :             new ConfigurationBackendDb(getComponentContext(), dbFile));
     210             :         //clean up data folders which are no longer used.
     211             :         //This must not be done in the same process where the help files
     212             :         //are still registers. Only after revoking and restarting OOo the folders
     213             :         //can be removed. This works now, because the extension manager is a singleton
     214             :         //and the backends are only create once per process.
     215         490 :         ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
     216         245 :         deleteUnusedFolders(OUString(), folders);
     217             : 
     218         245 :         configmgrini_verify_init( xCmdEnv );
     219             : 
     220             : #if HAVE_FEATURE_EXTENSIONS
     221             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     222         490 :         ::std::auto_ptr<PersistentMap> pMap;
     223             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     224         490 :         OUString aCompatURL( makeURL( getCachePath(), "registered_packages.pmap" ) );
     225             : 
     226             :         // Don't create it if it doesn't exist already
     227         245 :         if ( ::utl::UCBContentHelper::Exists( expandUnoRcUrl( aCompatURL ) ) )
     228             :         {
     229             :             try
     230             :             {
     231             :                 SAL_WNODEPRECATED_DECLARATIONS_PUSH
     232           0 :                 pMap = ::std::auto_ptr<PersistentMap>( new PersistentMap( aCompatURL, false ) );
     233             :                 SAL_WNODEPRECATED_DECLARATIONS_POP
     234             :             }
     235           0 :             catch (const Exception &e)
     236             :             {
     237           0 :                 OUStringBuffer aStr( "Exception loading legacy package database: '" );
     238           0 :                 aStr.append( e.Message );
     239           0 :                 aStr.append( "' - ignoring file, please remove it.\n" );
     240           0 :                 dp_misc::writeConsole( aStr.getStr() );
     241             :             }
     242             :         }
     243         490 :         m_registeredPackages = pMap;
     244             : #endif
     245         245 :      }
     246         245 : }
     247             : 
     248           0 : void BackendImpl::addDataToDb(
     249             :     OUString const & url, ConfigurationBackendDb::Data const & data)
     250             : {
     251           0 :     if (m_backendDb.get())
     252           0 :         m_backendDb->addEntry(url, data);
     253           0 : }
     254             : 
     255           0 : ::boost::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
     256             :     OUString const & url)
     257             : {
     258           0 :     ::boost::optional<ConfigurationBackendDb::Data> data;
     259           0 :     if (m_backendDb.get())
     260           0 :         data = m_backendDb->getEntry(url);
     261           0 :     return data;
     262             : }
     263             : 
     264           0 : void BackendImpl::revokeEntryFromDb(OUString const & url)
     265             : {
     266           0 :     if (m_backendDb.get())
     267           0 :         m_backendDb->revokeEntry(url);
     268           0 : }
     269             : 
     270           0 : bool BackendImpl::hasActiveEntry(OUString const & url)
     271             : {
     272           0 :     if (m_backendDb.get())
     273           0 :         return m_backendDb->hasActiveEntry(url);
     274           0 :     return false;
     275             : }
     276             : 
     277           0 : bool BackendImpl::activateEntry(OUString const & url)
     278             : {
     279           0 :     if (m_backendDb.get())
     280           0 :         return m_backendDb->activateEntry(url);
     281           0 :     return false;
     282             : }
     283             : 
     284             : 
     285             : 
     286             : // XPackageRegistry
     287             : 
     288             : Sequence< Reference<deployment::XPackageTypeInfo> >
     289         245 : BackendImpl::getSupportedPackageTypes() throw (RuntimeException, std::exception)
     290             : {
     291         245 :     return m_typeInfos;
     292             : }
     293           0 : void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
     294             :         throw (deployment::DeploymentException,
     295             :                uno::RuntimeException, std::exception)
     296             : {
     297           0 :     if (m_backendDb.get())
     298           0 :         m_backendDb->removeEntry(url);
     299           0 : }
     300             : 
     301             : // PackageRegistryBackend
     302             : 
     303           0 : Reference<deployment::XPackage> BackendImpl::bindPackage_(
     304             :     OUString const & url, OUString const & mediaType_,
     305             :     sal_Bool bRemoved, OUString const & identifier,
     306             :     Reference<XCommandEnvironment> const & xCmdEnv )
     307             : {
     308           0 :     OUString mediaType( mediaType_ );
     309           0 :     if (mediaType.isEmpty())
     310             :     {
     311             :         // detect media-type:
     312           0 :         ::ucbhelper::Content ucbContent;
     313           0 :         if (create_ucb_content( &ucbContent, url, xCmdEnv ))
     314             :         {
     315           0 :             const OUString title( StrTitle::getTitle( ucbContent ) );
     316           0 :             if (title.endsWithIgnoreAsciiCase( ".xcu" )) {
     317           0 :                 mediaType = "application/vnd.sun.star.configuration-data";
     318             :             }
     319           0 :             if (title.endsWithIgnoreAsciiCase( ".xcs" )) {
     320           0 :                 mediaType = "application/vnd.sun.star.configuration-schema";
     321           0 :             }
     322             :         }
     323           0 :         if (mediaType.isEmpty())
     324             :             throw lang::IllegalArgumentException(
     325           0 :                 StrCannotDetectMediaType::get() + url,
     326           0 :                 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
     327             :     }
     328             : 
     329           0 :     OUString type, subType;
     330           0 :     INetContentTypeParameterList params;
     331           0 :     if (INetContentTypes::parse( mediaType, type, subType, &params ))
     332             :     {
     333           0 :         if (type.equalsIgnoreAsciiCase("application"))
     334             :         {
     335           0 :             OUString name;
     336           0 :             if (!bRemoved)
     337             :             {
     338           0 :                 ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
     339           0 :                 name = StrTitle::getTitle( ucbContent );
     340             :             }
     341             : 
     342           0 :             ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
     343           0 :             if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-data"))
     344             :             {
     345             :                 return new PackageImpl(
     346             :                     this, url, name, m_xConfDataTypeInfo, false /* data file */,
     347           0 :                     bRemoved, identifier);
     348             :             }
     349           0 :             else if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-schema")) {
     350             :                 return new PackageImpl(
     351             :                     this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
     352           0 :                     bRemoved, identifier);
     353           0 :             }
     354             :         }
     355             :     }
     356             :     throw lang::IllegalArgumentException(
     357           0 :         StrUnsupportedMediaType::get() + mediaType,
     358             :         static_cast<OWeakObject *>(this),
     359           0 :         static_cast<sal_Int16>(-1) );
     360             : }
     361             : 
     362             : 
     363             : 
     364         245 : void BackendImpl::configmgrini_verify_init(
     365             :     Reference<XCommandEnvironment> const & xCmdEnv )
     366             : {
     367         245 :     if (transientMode())
     368         245 :         return;
     369         245 :     const ::osl::MutexGuard guard( getMutex() );
     370         245 :     if (! m_configmgrini_inited)
     371             :     {
     372             :         // common rc:
     373         245 :         ::ucbhelper::Content ucb_content;
     374         490 :         if (create_ucb_content(
     375             :                 &ucb_content,
     376         245 :                 makeURL( getCachePath(), "configmgr.ini" ),
     377         735 :                 xCmdEnv, false /* no throw */ ))
     378             :         {
     379           0 :             OUString line;
     380           0 :             if (readLine( &line, "SCHEMA=", ucb_content,
     381           0 :                           RTL_TEXTENCODING_UTF8 ))
     382             :             {
     383           0 :                 sal_Int32 index = RTL_CONSTASCII_LENGTH("SCHEMA=");
     384           0 :                 do {
     385           0 :                     OUString token( line.getToken( 0, ' ', index ).trim() );
     386           0 :                     if (!token.isEmpty()) {
     387             :                         //The  file may not exist anymore if a shared or bundled
     388             :                         //extension was removed, but it can still be in the configmgrini.
     389             :                         //After running XExtensionManager::synchronize, the configmgrini is
     390             :                         //cleaned up
     391           0 :                         m_xcs_files.push_back( token );
     392           0 :                     }
     393             :                 }
     394           0 :                 while (index >= 0);
     395             :             }
     396           0 :             if (readLine( &line, "DATA=", ucb_content,
     397           0 :                           RTL_TEXTENCODING_UTF8 )) {
     398           0 :                 sal_Int32 index = RTL_CONSTASCII_LENGTH("DATA=");
     399           0 :                 do {
     400           0 :                     OUString token( line.getToken( 0, ' ', index ).trim() );
     401           0 :                     if (!token.isEmpty())
     402             :                     {
     403           0 :                         if (token[ 0 ] == '?')
     404           0 :                             token = token.copy( 1 );
     405             :                         //The  file may not exist anymore if a shared or bundled
     406             :                         //extension was removed, but it can still be in the configmgrini.
     407             :                         //After running XExtensionManager::synchronize, the configmgrini is
     408             :                         //cleaned up
     409           0 :                         m_xcu_files.push_back( token );
     410           0 :                     }
     411             :                 }
     412           0 :                 while (index >= 0);
     413           0 :             }
     414             :         }
     415         245 :         m_configmgrini_modified = false;
     416         245 :         m_configmgrini_inited = true;
     417         245 :     }
     418             : }
     419             : 
     420             : 
     421         245 : void BackendImpl::configmgrini_flush(
     422             :     Reference<XCommandEnvironment> const & xCmdEnv )
     423             : {
     424         245 :     if (transientMode())
     425         245 :         return;
     426         245 :     if (!m_configmgrini_inited || !m_configmgrini_modified)
     427         245 :         return;
     428             : 
     429           0 :     OStringBuffer buf;
     430           0 :     if (! m_xcs_files.empty())
     431             :     {
     432           0 :         t_stringlist::const_iterator iPos( m_xcs_files.begin() );
     433           0 :         t_stringlist::const_iterator const iEnd( m_xcs_files.end() );
     434           0 :         buf.append( "SCHEMA=" );
     435           0 :         while (iPos != iEnd) {
     436             :             // encoded ASCII file-urls:
     437             :             const OString item(
     438           0 :                 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
     439           0 :             buf.append( item );
     440           0 :             ++iPos;
     441           0 :             if (iPos != iEnd)
     442           0 :                 buf.append( ' ' );
     443           0 :         }
     444           0 :         buf.append(LF);
     445             :     }
     446           0 :     if (! m_xcu_files.empty())
     447             :     {
     448           0 :         t_stringlist::const_iterator iPos( m_xcu_files.begin() );
     449           0 :         t_stringlist::const_iterator const iEnd( m_xcu_files.end() );
     450           0 :         buf.append( "DATA=" );
     451           0 :         while (iPos != iEnd) {
     452             :             // encoded ASCII file-urls:
     453             :             const OString item(
     454           0 :                 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
     455           0 :             buf.append( item );
     456           0 :             ++iPos;
     457           0 :             if (iPos != iEnd)
     458           0 :                 buf.append( ' ' );
     459           0 :         }
     460           0 :         buf.append(LF);
     461             :     }
     462             : 
     463             :     // write configmgr.ini:
     464             :     const Reference<io::XInputStream> xData(
     465             :         ::xmlscript::createInputStream(
     466             :             ::rtl::ByteSequence(
     467           0 :                 reinterpret_cast<sal_Int8 const *>(buf.getStr()),
     468           0 :                 buf.getLength() ) ) );
     469             :     ::ucbhelper::Content ucb_content(
     470           0 :         makeURL( getCachePath(), "configmgr.ini" ), xCmdEnv, m_xComponentContext );
     471           0 :     ucb_content.writeStream( xData, true /* replace existing */ );
     472             : 
     473           0 :     m_configmgrini_modified = false;
     474             : }
     475             : 
     476             : 
     477           0 : bool BackendImpl::addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url_,
     478             :                               Reference<XCommandEnvironment> const & xCmdEnv )
     479             : {
     480           0 :     const OUString rcterm( isURL ? dp_misc::makeRcTerm(url_) : url_ );
     481           0 :     const ::osl::MutexGuard guard( getMutex() );
     482           0 :     configmgrini_verify_init( xCmdEnv );
     483           0 :     t_stringlist & rSet = getFiles(isSchema);
     484           0 :     if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
     485           0 :         rSet.push_front( rcterm ); // prepend to list, thus overriding
     486             :         // write immediately:
     487           0 :         m_configmgrini_modified = true;
     488           0 :         configmgrini_flush( xCmdEnv );
     489           0 :         return true;
     490             :     }
     491             :     else
     492           0 :         return false;
     493             : }
     494             : 
     495             : 
     496           0 : bool BackendImpl::removeFromConfigmgrIni(
     497             :     bool isSchema, OUString const & url_,
     498             :     Reference<XCommandEnvironment> const & xCmdEnv )
     499             : {
     500           0 :     const OUString rcterm( dp_misc::makeRcTerm(url_) );
     501           0 :     const ::osl::MutexGuard guard( getMutex() );
     502           0 :     configmgrini_verify_init( xCmdEnv );
     503           0 :     t_stringlist & rSet = getFiles(isSchema);
     504           0 :     t_stringlist::iterator i(std::find(rSet.begin(), rSet.end(), rcterm));
     505           0 :     if (i == rSet.end() && !isSchema)
     506             :     {
     507             :         //in case the xcu contained %origin% then the configmr.ini contains the
     508             :         //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
     509             :         //However, m_url (getURL()) contains the URL for the file in the actual
     510             :         //extension installatation.
     511           0 :         ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
     512           0 :         if (data)
     513           0 :             i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
     514             :     }
     515           0 :     if (i == rSet.end()) {
     516           0 :         return false;
     517             :     }
     518           0 :     rSet.erase(i);
     519             :     // write immediately:
     520           0 :     m_configmgrini_modified = true;
     521           0 :     configmgrini_flush( xCmdEnv );
     522           0 :     return true;
     523             : }
     524             : 
     525             : 
     526             : // Package
     527             : 
     528             : 
     529           0 : BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
     530             : {
     531           0 :     BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
     532           0 :     if (NULL == pBackend)
     533             :     {
     534             :         //May throw a DisposedException
     535           0 :         check();
     536             :         //We should never get here...
     537             :         throw RuntimeException(
     538             :             "Failed to get the BackendImpl",
     539           0 :             static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
     540             :     }
     541           0 :     return pBackend;
     542             : }
     543             : 
     544             : beans::Optional< beans::Ambiguous<sal_Bool> >
     545           0 : BackendImpl::PackageImpl::isRegistered_(
     546             :     ::osl::ResettableMutexGuard &,
     547             :     ::rtl::Reference<AbortChannel> const &,
     548             :     Reference<XCommandEnvironment> const & )
     549             : {
     550           0 :     BackendImpl * that = getMyBackend();
     551             : 
     552           0 :     bool bReg = false;
     553           0 :     if (that->hasActiveEntry(getURL()))
     554           0 :         bReg = true;
     555             : 
     556             : #if HAVE_FEATURE_EXTENSIONS
     557           0 :     const OUString url(getURL());
     558           0 :     if (!bReg && that->m_registeredPackages.get())
     559             :     {
     560             :         // fallback for user extension registered in berkeley DB
     561             :         bReg = that->m_registeredPackages->has(
     562           0 :             OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));
     563             :     }
     564             : #endif
     565             :     return beans::Optional< beans::Ambiguous<sal_Bool> >(
     566           0 :         true, beans::Ambiguous<sal_Bool>( bReg, false ) );
     567             : }
     568             : 
     569             : 
     570           0 : OUString encodeForXml( OUString const & text )
     571             : {
     572             :     // encode conforming xml:
     573           0 :     sal_Int32 len = text.getLength();
     574           0 :     OUStringBuffer buf;
     575           0 :     for ( sal_Int32 pos = 0; pos < len; ++pos )
     576             :     {
     577           0 :         sal_Unicode c = text[ pos ];
     578           0 :         switch (c) {
     579             :         case '<':
     580           0 :             buf.appendAscii( "&lt;" );
     581           0 :             break;
     582             :         case '>':
     583           0 :             buf.appendAscii( "&gt;" );
     584           0 :             break;
     585             :         case '&':
     586           0 :             buf.appendAscii( "&amp;" );
     587           0 :             break;
     588             :         case '\'':
     589           0 :             buf.appendAscii( "&apos;" );
     590           0 :             break;
     591             :         case '\"':
     592           0 :             buf.appendAscii( "&quot;" );
     593           0 :             break;
     594             :         default:
     595           0 :             buf.append( c );
     596           0 :             break;
     597             :         }
     598             :     }
     599           0 :     return buf.makeStringAndClear();
     600             : }
     601             : 
     602             : 
     603           0 : OUString replaceOrigin(
     604             :     OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, Reference< XComponentContext > const & xContext, bool & out_replaced)
     605             : {
     606             :     // looking for %origin%:
     607           0 :     ::ucbhelper::Content ucb_content( url, xCmdEnv, xContext );
     608           0 :     ::rtl::ByteSequence bytes( readFile( ucb_content ) );
     609           0 :     ::rtl::ByteSequence filtered( bytes.getLength() * 2,
     610           0 :                                   ::rtl::BYTESEQ_NODEFAULT );
     611           0 :     bool use_filtered = false;
     612           0 :     OString origin;
     613             :     sal_Char const * pBytes = reinterpret_cast<sal_Char const *>(
     614           0 :         bytes.getConstArray());
     615           0 :     sal_Size nBytes = bytes.getLength();
     616           0 :     sal_Int32 write_pos = 0;
     617           0 :     while (nBytes > 0)
     618             :     {
     619           0 :         sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
     620           0 :         if (index < 0) {
     621           0 :             if (! use_filtered) // opt
     622           0 :                 break;
     623           0 :             index = nBytes;
     624             :         }
     625             : 
     626           0 :         if ((write_pos + index) > filtered.getLength())
     627           0 :             filtered.realloc( (filtered.getLength() + index) * 2 );
     628           0 :         memcpy( filtered.getArray() + write_pos, pBytes, index );
     629           0 :         write_pos += index;
     630           0 :         pBytes += index;
     631           0 :         nBytes -= index;
     632           0 :         if (nBytes == 0)
     633           0 :             break;
     634             : 
     635             :         // consume %:
     636           0 :         ++pBytes;
     637           0 :         --nBytes;
     638           0 :         sal_Char const * pAdd = "%";
     639           0 :         sal_Int32 nAdd = 1;
     640           0 :         if (nBytes > 1 && pBytes[ 0 ] == '%')
     641             :         {
     642             :             // %% => %
     643           0 :             ++pBytes;
     644           0 :             --nBytes;
     645           0 :             use_filtered = true;
     646             :         }
     647           0 :         else if (rtl_str_shortenedCompare_WithLength(
     648             :                      pBytes, nBytes,
     649             :                      "origin%",
     650           0 :                      RTL_CONSTASCII_LENGTH("origin%"),
     651           0 :                      RTL_CONSTASCII_LENGTH("origin%")) == 0)
     652             :         {
     653           0 :             if (origin.isEmpty()) {
     654             :                 // encode only once
     655           0 :                 origin = OUStringToOString(
     656             :                     encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
     657             :                     // xxx todo: encode always for UTF-8? => lookup doc-header?
     658           0 :                     RTL_TEXTENCODING_UTF8 );
     659             :             }
     660           0 :             pAdd = origin.getStr();
     661           0 :             nAdd = origin.getLength();
     662           0 :             pBytes += RTL_CONSTASCII_LENGTH("origin%");
     663           0 :             nBytes -= RTL_CONSTASCII_LENGTH("origin%");
     664           0 :             use_filtered = true;
     665             :         }
     666           0 :         if ((write_pos + nAdd) > filtered.getLength())
     667           0 :             filtered.realloc( (filtered.getLength() + nAdd) * 2 );
     668           0 :         memcpy( filtered.getArray() + write_pos, pAdd, nAdd );
     669           0 :         write_pos += nAdd;
     670             :     }
     671           0 :     if (!use_filtered)
     672           0 :         return url;
     673           0 :     if (write_pos < filtered.getLength())
     674           0 :         filtered.realloc( write_pos );
     675           0 :     OUString newUrl(url);
     676           0 :     if (!destFolder.isEmpty())
     677             :     {
     678             :         //get the file name of the xcu and add it to the url of the temporary folder
     679           0 :         sal_Int32 i = url.lastIndexOf('/');
     680           0 :         newUrl = destFolder + url.copy(i);
     681             :     }
     682             : 
     683             :     ucbhelper::Content(newUrl, xCmdEnv, xContext).writeStream(
     684           0 :         xmlscript::createInputStream(filtered), true);
     685           0 :     out_replaced = true;
     686           0 :     return newUrl;
     687             : }
     688             : 
     689             : 
     690           0 : void BackendImpl::PackageImpl::processPackage_(
     691             :     ::osl::ResettableMutexGuard &,
     692             :     bool doRegisterPackage,
     693             :     bool startup,
     694             :     ::rtl::Reference<AbortChannel> const &,
     695             :     Reference<XCommandEnvironment> const & xCmdEnv )
     696             : {
     697           0 :     BackendImpl * that = getMyBackend();
     698           0 :     OUString url( getURL() );
     699             : 
     700           0 :     if (doRegisterPackage)
     701             :     {
     702           0 :         if (getMyBackend()->activateEntry(getURL()))
     703             :         {
     704           0 :             ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
     705             :             OSL_ASSERT(data);
     706           0 :             that->addToConfigmgrIni( m_isSchema, false, data->iniEntry, xCmdEnv );
     707             :         }
     708             :         else
     709             :         {
     710           0 :             ConfigurationBackendDb::Data data;
     711           0 :             if (!m_isSchema)
     712             :             {
     713           0 :                 const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
     714           0 :                 bool out_replaced = false;
     715           0 :                 url = replaceOrigin(url, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
     716           0 :                 if (out_replaced)
     717           0 :                     data.dataUrl = sModFolder;
     718             :                 else
     719           0 :                     deleteTempFolder(sModFolder);
     720             :             }
     721             :             //No need for live-deployment for bundled extension, because OOo
     722             :             //restarts after installation
     723           0 :             if (that->m_eContext != CONTEXT_BUNDLED
     724           0 :                 && !startup)
     725             :             {
     726           0 :                 if (m_isSchema)
     727             :                 {
     728             :                     com::sun::star::configuration::Update::get(
     729           0 :                         that->m_xComponentContext)->insertExtensionXcsFile(
     730           0 :                             that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
     731             :                 }
     732             :                 else
     733             :                 {
     734             :                     com::sun::star::configuration::Update::get(
     735           0 :                         that->m_xComponentContext)->insertExtensionXcuFile(
     736           0 :                             that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
     737             :                 }
     738             :             }
     739           0 :             that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
     740           0 :             data.iniEntry = dp_misc::makeRcTerm(url);
     741           0 :             that->addDataToDb(getURL(), data);
     742             :         }
     743             :     }
     744             :     else // revoke
     745             :     {
     746             : #if HAVE_FEATURE_EXTENSIONS
     747           0 :         if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv) &&
     748           0 :             that->m_registeredPackages.get()) {
     749             :             // Obsolete package database handling - should be removed for LibreOffice 4.0
     750             :             t_string2string_map entries(
     751           0 :                 that->m_registeredPackages->getEntries());
     752           0 :             for (t_string2string_map::iterator i(entries.begin());
     753           0 :                  i != entries.end(); ++i)
     754             :             {
     755             :                 //If the xcu file was installed before the configmgr was chaned
     756             :                 //to use the configmgr.ini, one needed to rebuild to whole directory
     757             :                 //structur containing the xcu, xcs files from all extensions. Now,
     758             :                 //we just add all other xcu/xcs files to the configmgr.ini instead of
     759             :                 //rebuilding the directory structure.
     760             :                 OUString url2(
     761           0 :                     OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
     762           0 :                 if (url2 != url) {
     763           0 :                    bool schema = i->second.equalsIgnoreAsciiCase(
     764           0 :                        "vnd.sun.star.configuration-schema");
     765           0 :                    OUString url_replaced(url2);
     766           0 :                    ConfigurationBackendDb::Data data;
     767           0 :                    if (!schema)
     768             :                    {
     769           0 :                        const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
     770           0 :                        bool out_replaced = false;
     771           0 :                        url_replaced = replaceOrigin(
     772           0 :                            url2, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
     773           0 :                        if (out_replaced)
     774           0 :                            data.dataUrl = sModFolder;
     775             :                        else
     776           0 :                            deleteTempFolder(sModFolder);
     777             :                    }
     778           0 :                    that->addToConfigmgrIni(schema, true, url_replaced, xCmdEnv);
     779           0 :                    data.iniEntry = dp_misc::makeRcTerm(url_replaced);
     780           0 :                    that->addDataToDb(url2, data);
     781             :                 }
     782           0 :                 that->m_registeredPackages->erase(i->first);
     783           0 :             }
     784             :             try
     785             :             {
     786             :                 ::ucbhelper::Content(
     787           0 :                     makeURL( that->getCachePath(), "registry" ),
     788           0 :                     xCmdEnv, that->getComponentContext() ).executeCommand(
     789           0 :                         "delete", Any( true /* delete physically */ ) );
     790             :             }
     791           0 :             catch(const Exception&)
     792             :             {
     793             :                 OSL_ASSERT(false);
     794           0 :             }
     795             :         }
     796             : #endif
     797           0 :         ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
     798             :         //If an xcu file was life deployed then always a data entry is written.
     799             :         //If the xcu file was already in the configmr.ini then there is also
     800             :         //a data entry
     801           0 :         if (!m_isSchema && data)
     802             :         {
     803             :             com::sun::star::configuration::Update::get(
     804           0 :                 that->m_xComponentContext)->removeExtensionXcuFile(expandUnoRcTerm(data->iniEntry));
     805             :         }
     806           0 :         that->revokeEntryFromDb(url);
     807           0 :     }
     808           0 : }
     809             : 
     810             : } // anon namespace
     811             : 
     812             : namespace sdecl = comphelper::service_decl;
     813          67 : sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
     814          67 : extern sdecl::ServiceDecl const serviceDecl(
     815             :     serviceBI,
     816             :     "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
     817             :     BACKEND_SERVICE_NAME );
     818             : 
     819             : } // namespace configuration
     820             : } // namespace backend
     821         201 : } // namespace dp_registry
     822             : 
     823             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10