/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_desktop.hxx"

//TODO: Large parts of this file were copied from dp_component.cxx; those parts
// should be consolidated.

#include "dp_configuration.hrc"
#include "dp_backend.h"
#include "dp_persmap.h"
#include "dp_ucb.h"
#include "rtl/string.hxx"
#include "rtl/ustrbuf.hxx"
#include "rtl/uri.hxx"
#include "rtl/memory.h"
#include "osl/file.hxx"
#include "cppuhelper/exc_hlp.hxx"
#include "ucbhelper/content.hxx"
#include "comphelper/anytostring.hxx"
#include "comphelper/servicedecl.hxx"
#include "xmlscript/xml_helper.hxx"
#include "svl/inettype.hxx"
#include "com/sun/star/configuration/Update.hpp"
#include "com/sun/star/ucb/NameClash.hpp"
#include "com/sun/star/io/XActiveDataSink.hpp"
#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
#include "com/sun/star/util/XRefreshable.hpp"
#include <list>
#include <memory>

#include "dp_configurationbackenddb.hxx"

using namespace ::dp_misc;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using ::rtl::OUString;

namespace dp_registry {
namespace backend {
namespace configuration {
namespace {

typedef ::std::list<OUString> t_stringlist;

//==============================================================================
class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
{
    class PackageImpl : public ::dp_registry::backend::Package
    {
        BackendImpl * getMyBackend() const ;

        const bool m_isSchema;

        // Package
        virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
            ::osl::ResettableMutexGuard & guard,
            ::rtl::Reference<AbortChannel> const & abortChannel,
            Reference<XCommandEnvironment> const & xCmdEnv );
        virtual void processPackage_(
            ::osl::ResettableMutexGuard & guard,
            bool registerPackage,
            bool startup,
            ::rtl::Reference<AbortChannel> const & abortChannel,
            Reference<XCommandEnvironment> const & xCmdEnv );

    public:
        inline PackageImpl(
            ::rtl::Reference<PackageRegistryBackend> const & myBackend,
            OUString const & url, OUString const & name,
            Reference<deployment::XPackageTypeInfo> const & xPackageType,
            bool isSchema, bool bRemoved, OUString const & identifier)
            : Package( myBackend, url, name, name /* display-name */,
                       xPackageType, bRemoved, identifier),
              m_isSchema( isSchema )
            {}
    };
    friend class PackageImpl;

    t_stringlist m_xcs_files;
    t_stringlist m_xcu_files;
    t_stringlist & getFiles( bool xcs ) {
        return xcs ? m_xcs_files : m_xcu_files;
    }

    bool m_configmgrini_inited;
    bool m_configmgrini_modified;
    std::auto_ptr<ConfigurationBackendDb> m_backendDb;

    // PackageRegistryBackend
    virtual Reference<deployment::XPackage> bindPackage_(
        OUString const & url, OUString const & mediaType, sal_Bool bRemoved,
        OUString const & identifier,
        Reference<XCommandEnvironment> const & xCmdEnv );

    ::std::auto_ptr<PersistentMap> m_registeredPackages;
        // for backwards compatibility

    virtual void SAL_CALL disposing();

    const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
    const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
    Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;

    void configmgrini_verify_init(
        Reference<XCommandEnvironment> const & xCmdEnv );
    void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );

    /* The parameter isURL is false in the case of adding the conf:ini-entry
       value from the backend db. This entry already contains the path as it
       is used in the configmgr.ini.
     */
    bool addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url,
                     Reference<XCommandEnvironment> const & xCmdEnv );
    bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
                          Reference<XCommandEnvironment> const & xCmdEnv );

    void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
    ::boost::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
    void revokeEntryFromDb(OUString const & url);
    ::std::list<OUString> getAllIniEntries();
    bool hasActiveEntry(OUString const & url);
    bool activateEntry(OUString const & url);

public:
    BackendImpl( Sequence<Any> const & args,
                 Reference<XComponentContext> const & xComponentContext );

    // XPackageRegistry
    virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
    getSupportedPackageTypes() throw (RuntimeException);
    virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType)
        throw (deployment::DeploymentException,
               uno::RuntimeException);

    using PackageRegistryBackend::disposing;
};

//______________________________________________________________________________
void BackendImpl::disposing()
{
    try {
        configmgrini_flush( Reference<XCommandEnvironment>() );

        PackageRegistryBackend::disposing();
    }
    catch (RuntimeException &) {
        throw;
    }
    catch (Exception &) {
        Any exc( ::cppu::getCaughtException() );
        throw lang::WrappedTargetRuntimeException(
            OUSTR("caught unexpected exception while disposing..."),
            static_cast<OWeakObject *>(this), exc );
    }
}

//______________________________________________________________________________
BackendImpl::BackendImpl(
    Sequence<Any> const & args,
    Reference<XComponentContext> const & xComponentContext )
    : PackageRegistryBackend( args, xComponentContext ),
      m_configmgrini_inited( false ),
      m_configmgrini_modified( false ),
      m_xConfDataTypeInfo( new Package::TypeInfo(
                               OUSTR("application/"
                                     "vnd.sun.star.configuration-data"),
                               OUSTR("*.xcu"),
                               getResourceString(RID_STR_CONF_DATA),
                               RID_IMG_CONF_XML, RID_IMG_CONF_XML_HC ) ),
      m_xConfSchemaTypeInfo( new Package::TypeInfo(
                                 OUSTR("application/"
                                       "vnd.sun.star.configuration-schema"),
                                 OUSTR("*.xcs"),
                                 getResourceString(RID_STR_CONF_SCHEMA),
                                 RID_IMG_CONF_XML, RID_IMG_CONF_XML_HC ) ),
      m_typeInfos( 2 )
{
    m_typeInfos[ 0 ] = m_xConfDataTypeInfo;
    m_typeInfos[ 1 ] = m_xConfSchemaTypeInfo;

    const Reference<XCommandEnvironment> xCmdEnv;

    if (transientMode())
    {
        //TODO
    }
    else
    {
        OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml"));
        m_backendDb.reset(
            new ConfigurationBackendDb(getComponentContext(), dbFile));
        //clean up data folders which are no longer used.
        //This must not be done in the same process where the help files
        //are still registers. Only after revoking and restarting OOo the folders
        //can be removed. This works now, because the extension manager is a singleton
        //and the backends are only create once per process.
        ::std::list<OUString> folders = m_backendDb->getAllDataUrls();
        deleteUnusedFolders(OUString(), folders);


        configmgrini_verify_init( xCmdEnv );
        m_registeredPackages.reset(
            new PersistentMap(
                makeURL( getCachePath(), OUSTR("registered_packages.pmap") ),
                false ) );
     }
}

void BackendImpl::addDataToDb(
    OUString const & url, ConfigurationBackendDb::Data const & data)
{
    if (m_backendDb.get())
        m_backendDb->addEntry(url, data);
}

::boost::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
    OUString const & url)
{
    ::boost::optional<ConfigurationBackendDb::Data> data;
    if (m_backendDb.get())
        data = m_backendDb->getEntry(url);
    return data;
}

void BackendImpl::revokeEntryFromDb(OUString const & url)
{
    if (m_backendDb.get())
        m_backendDb->revokeEntry(url);
}

::std::list<OUString> BackendImpl::getAllIniEntries()
{
    if (m_backendDb.get())
        return m_backendDb->getAllIniEntries();
    else
        return ::std::list<OUString>();
}

bool BackendImpl::hasActiveEntry(OUString const & url)
{
    if (m_backendDb.get())
        return m_backendDb->hasActiveEntry(url);
    return false;
}

bool BackendImpl::activateEntry(OUString const & url)
{
    if (m_backendDb.get())
        return m_backendDb->activateEntry(url);
    return false;
}



// XPackageRegistry
//______________________________________________________________________________
Sequence< Reference<deployment::XPackageTypeInfo> >
BackendImpl::getSupportedPackageTypes() throw (RuntimeException)
{
    return m_typeInfos;
}
void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
        throw (deployment::DeploymentException,
               uno::RuntimeException)
{
    if (m_backendDb.get())
        m_backendDb->removeEntry(url);
}

// PackageRegistryBackend
//______________________________________________________________________________
Reference<deployment::XPackage> BackendImpl::bindPackage_(
    OUString const & url, OUString const & mediaType_,
    sal_Bool bRemoved, OUString const & identifier,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    OUString mediaType( mediaType_ );
    if (mediaType.getLength() == 0)
    {
        // detect media-type:
        ::ucbhelper::Content ucbContent;
        if (create_ucb_content( &ucbContent, url, xCmdEnv ))
        {
            const OUString title( ucbContent.getPropertyValue(
                                      StrTitle::get() ).get<OUString>() );
            if (title.endsWithIgnoreAsciiCaseAsciiL(
                    RTL_CONSTASCII_STRINGPARAM(".xcu") )) {
                mediaType = OUSTR("application/"
                                  "vnd.sun.star.configuration-data");
            }
            if (title.endsWithIgnoreAsciiCaseAsciiL(
                    RTL_CONSTASCII_STRINGPARAM(".xcs") )) {
                mediaType = OUSTR("application/"
                                  "vnd.sun.star.configuration-schema");
            }
        }
        if (mediaType.getLength() == 0)
            throw lang::IllegalArgumentException(
                StrCannotDetectMediaType::get() + url,
                static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
    }

    String type, subType;
    INetContentTypeParameterList params;
    if (INetContentTypes::parse( mediaType, type, subType, &params ))
    {
        if (type.EqualsIgnoreCaseAscii("application"))
        {
            OUString name;
            if (!bRemoved)
            {
                ::ucbhelper::Content ucbContent( url, xCmdEnv );
                name = ucbContent.getPropertyValue(
                    StrTitle::get() ).get<OUString>();
            }

            ::ucbhelper::Content ucbContent( url, xCmdEnv );
            if (subType.EqualsIgnoreCaseAscii(
                    "vnd.sun.star.configuration-data"))
            {
                return new PackageImpl(
                    this, url, name, m_xConfDataTypeInfo, false /* data file */,
                    bRemoved, identifier);
            }
            else if (subType.EqualsIgnoreCaseAscii(
                         "vnd.sun.star.configuration-schema")) {
                return new PackageImpl(
                    this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
                    bRemoved, identifier);
            }
        }
    }
    throw lang::IllegalArgumentException(
        StrUnsupportedMediaType::get() + mediaType,
        static_cast<OWeakObject *>(this),
        static_cast<sal_Int16>(-1) );
}

//##############################################################################

//______________________________________________________________________________
void BackendImpl::configmgrini_verify_init(
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    if (transientMode())
        return;
    const ::osl::MutexGuard guard( getMutex() );
    if (! m_configmgrini_inited)
    {
        // common rc:
        ::ucbhelper::Content ucb_content;
        if (create_ucb_content(
                &ucb_content,
                makeURL( getCachePath(), OUSTR("configmgr.ini") ),
                xCmdEnv, false /* no throw */ ))
        {
            OUString line;
            if (readLine( &line, OUSTR("SCHEMA="), ucb_content,
                          RTL_TEXTENCODING_UTF8 ))
            {
                sal_Int32 index = sizeof ("SCHEMA=") - 1;
                do {
                    OUString token( line.getToken( 0, ' ', index ).trim() );
                    if (token.getLength() > 0) {
                        //The  file may not exist anymore if a shared or bundled
                        //extension was removed, but it can still be in the configmgrini.
                        //After running XExtensionManager::synchronize, the configmgrini is
                        //cleaned up
                        m_xcs_files.push_back( token );
                    }
                }
                while (index >= 0);
            }
            if (readLine( &line, OUSTR("DATA="), ucb_content,
                          RTL_TEXTENCODING_UTF8 )) {
                sal_Int32 index = sizeof ("DATA=") - 1;
                do {
                    OUString token( line.getToken( 0, ' ', index ).trim() );
                    if (token.getLength() > 0)
                    {
                        if (token[ 0 ] == '?')
                            token = token.copy( 1 );
                        //The  file may not exist anymore if a shared or bundled
                        //extension was removed, but it can still be in the configmgrini.
                        //After running XExtensionManager::synchronize, the configmgrini is
                        //cleaned up
                        m_xcu_files.push_back( token );
                    }
                }
                while (index >= 0);
            }
        }
        m_configmgrini_modified = false;
        m_configmgrini_inited = true;
    }
}

//______________________________________________________________________________
void BackendImpl::configmgrini_flush(
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    if (transientMode())
        return;
    if (!m_configmgrini_inited || !m_configmgrini_modified)
        return;

    ::rtl::OStringBuffer buf;
    if (! m_xcs_files.empty())
    {
        t_stringlist::const_iterator iPos( m_xcs_files.begin() );
        t_stringlist::const_iterator const iEnd( m_xcs_files.end() );
        buf.append( RTL_CONSTASCII_STRINGPARAM("SCHEMA=") );
        while (iPos != iEnd) {
            // encoded ASCII file-urls:
            const ::rtl::OString item(
                ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
            buf.append( item );
            ++iPos;
            if (iPos != iEnd)
                buf.append( ' ' );
        }
        buf.append(LF);
    }
    if (! m_xcu_files.empty())
    {
        t_stringlist::const_iterator iPos( m_xcu_files.begin() );
        t_stringlist::const_iterator const iEnd( m_xcu_files.end() );
        buf.append( RTL_CONSTASCII_STRINGPARAM("DATA=") );
        while (iPos != iEnd) {
            // encoded ASCII file-urls:
            const ::rtl::OString item(
                ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
            buf.append( item );
            ++iPos;
            if (iPos != iEnd)
                buf.append( ' ' );
        }
        buf.append(LF);
    }

    // write configmgr.ini:
    const Reference<io::XInputStream> xData(
        ::xmlscript::createInputStream(
            ::rtl::ByteSequence(
                reinterpret_cast<sal_Int8 const *>(buf.getStr()),
                buf.getLength() ) ) );
    ::ucbhelper::Content ucb_content(
        makeURL( getCachePath(), OUSTR("configmgr.ini") ), xCmdEnv );
    ucb_content.writeStream( xData, true /* replace existing */ );

    m_configmgrini_modified = false;
}

//______________________________________________________________________________
bool BackendImpl::addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url_,
                              Reference<XCommandEnvironment> const & xCmdEnv )
{
    const OUString rcterm( isURL ? dp_misc::makeRcTerm(url_) : url_ );
    const ::osl::MutexGuard guard( getMutex() );
    configmgrini_verify_init( xCmdEnv );
    t_stringlist & rSet = getFiles(isSchema);
    if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
        rSet.push_front( rcterm ); // prepend to list, thus overriding
        // write immediately:
        m_configmgrini_modified = true;
        configmgrini_flush( xCmdEnv );
        return true;
    }
    else
        return false;
}

//______________________________________________________________________________
bool BackendImpl::removeFromConfigmgrIni(
    bool isSchema, OUString const & url_,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    const OUString rcterm( dp_misc::makeRcTerm(url_) );
    const ::osl::MutexGuard guard( getMutex() );
    configmgrini_verify_init( xCmdEnv );
    t_stringlist & rSet = getFiles(isSchema);
    t_stringlist::iterator i(std::find(rSet.begin(), rSet.end(), rcterm));
    if (i == rSet.end() && !isSchema)
    {
        //in case the xcu contained %origin% then the configmr.ini contains the
        //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
        //However, m_url (getURL()) contains the URL for the file in the actual
        //extension installation.
        ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
        if (data)
            i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
    }
    if (i == rSet.end()) {
        return false;
    }
    rSet.erase(i);
    // write immediately:
    m_configmgrini_modified = true;
    configmgrini_flush( xCmdEnv );
    return true;
}

//##############################################################################

// Package
//______________________________________________________________________________

BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
{
    BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
    if (NULL == pBackend)
    {
        //May throw a DisposedException
        check();
        //We should never get here...
        throw RuntimeException(
            OUSTR("Failed to get the BackendImpl"),
            static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
    }
    return pBackend;
}

beans::Optional< beans::Ambiguous<sal_Bool> >
BackendImpl::PackageImpl::isRegistered_(
    ::osl::ResettableMutexGuard &,
    ::rtl::Reference<AbortChannel> const &,
    Reference<XCommandEnvironment> const & )
{
    BackendImpl * that = getMyBackend();
    const rtl::OUString url(getURL());

    bool bReg = false;
    if (that->hasActiveEntry(getURL()))
        bReg = true;
    if (!bReg)
        //fallback for user extension registered in berkeley DB
        bReg = that->m_registeredPackages->has(
            rtl::OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));

	return beans::Optional< beans::Ambiguous<sal_Bool> >(
        true, beans::Ambiguous<sal_Bool>( bReg, false ) );
}

//------------------------------------------------------------------------------
OUString encodeForXml( OUString const & text )
{
    // encode conforming xml:
    sal_Int32 len = text.getLength();
    ::rtl::OUStringBuffer buf;
    for ( sal_Int32 pos = 0; pos < len; ++pos )
    {
        sal_Unicode c = text[ pos ];
        switch (c) {
        case '<':
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&lt;") );
            break;
        case '>':
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&gt;") );
            break;
        case '&':
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&amp;") );
            break;
        case '\'':
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&apos;") );
            break;
        case '\"':
            buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("&quot;") );
            break;
        default:
            buf.append( c );
            break;
        }
    }
    return buf.makeStringAndClear();
}

//______________________________________________________________________________
OUString replaceOrigin(
    OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, bool & out_replaced)
{
    // looking for %origin%:
    ::ucbhelper::Content ucb_content( url, xCmdEnv );
    ::rtl::ByteSequence bytes( readFile( ucb_content ) );
    ::rtl::ByteSequence filtered( bytes.getLength() * 2,
                                  ::rtl::BYTESEQ_NODEFAULT );
    bool use_filtered = false;
    ::rtl::OString origin;
    sal_Char const * pBytes = reinterpret_cast<sal_Char const *>(
        bytes.getConstArray());
    sal_Size nBytes = bytes.getLength();
    sal_Int32 write_pos = 0;
    while (nBytes > 0)
    {
        sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
        if (index < 0) {
            if (! use_filtered) // opt
                break;
            index = nBytes;
        }

        if ((write_pos + index) > filtered.getLength())
            filtered.realloc( (filtered.getLength() + index) * 2 );
        rtl_copyMemory( filtered.getArray() + write_pos, pBytes, index );
        write_pos += index;
        pBytes += index;
        nBytes -= index;
        if (nBytes == 0)
            break;

        // consume %:
        ++pBytes;
        --nBytes;
        sal_Char const * pAdd = "%";
        sal_Int32 nAdd = 1;
        if (nBytes > 1 && pBytes[ 0 ] == '%')
        {
            // %% => %
            ++pBytes;
            --nBytes;
            use_filtered = true;
        }
        else if (rtl_str_shortenedCompare_WithLength(
                     pBytes, nBytes,
                     RTL_CONSTASCII_STRINGPARAM("origin%"),
                     sizeof ("origin%") - 1 ) == 0)
        {
            if (origin.getLength() == 0) {
                // encode only once
                origin = ::rtl::OUStringToOString(
                    encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
                    // xxx todo: encode always for UTF-8? => lookup doc-header?
                    RTL_TEXTENCODING_UTF8 );
            }
            pAdd = origin.getStr();
            nAdd = origin.getLength();
            pBytes += (sizeof ("origin%") - 1);
            nBytes -= (sizeof ("origin%") - 1);
            use_filtered = true;
        }
        if ((write_pos + nAdd) > filtered.getLength())
            filtered.realloc( (filtered.getLength() + nAdd) * 2 );
        rtl_copyMemory( filtered.getArray() + write_pos, pAdd, nAdd );
        write_pos += nAdd;
    }
    if (!use_filtered)
        return url;
    if (write_pos < filtered.getLength())
        filtered.realloc( write_pos );
    rtl::OUString newUrl(url);
    if (destFolder.getLength())
    {
        //get the file name of the xcu and add it to the url of the temporary folder
        sal_Int32 i = url.lastIndexOf('/');
        newUrl = destFolder + url.copy(i);
    }

    ucbhelper::Content(newUrl, xCmdEnv).writeStream(
        xmlscript::createInputStream(filtered), true);
    out_replaced = true;
    return newUrl;
}

//______________________________________________________________________________
void BackendImpl::PackageImpl::processPackage_(
    ::osl::ResettableMutexGuard &,
    bool doRegisterPackage,
    bool startup,
    ::rtl::Reference<AbortChannel> const &,
    Reference<XCommandEnvironment> const & xCmdEnv )
{
    BackendImpl * that = getMyBackend();
    OUString url( getURL() );

    if (doRegisterPackage)
    {
        if (getMyBackend()->activateEntry(getURL()))
        {
            ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
            OSL_ASSERT(data);
            that->addToConfigmgrIni( m_isSchema, false, data->iniEntry, xCmdEnv );
        }
        else
        {
            ConfigurationBackendDb::Data data;
            if (!m_isSchema)
            {
                const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
                bool out_replaced = false;
                url = replaceOrigin(url, sModFolder, xCmdEnv, out_replaced);
                if (out_replaced)
                    data.dataUrl = sModFolder;
                else
                    deleteTempFolder(sModFolder);
            }
            //No need for live-deployment for bundled extension, because OOo
            //restarts after installation
            if (that->m_eContext != CONTEXT_BUNDLED
                && that->m_eContext != CONTEXT_BUNDLED_PREREG
                && !startup)
            {
                if (m_isSchema)
                {
                    com::sun::star::configuration::Update::get(
                        that->m_xComponentContext)->insertExtensionXcsFile(
                            that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
                }
                else
                {
                    com::sun::star::configuration::Update::get(
                        that->m_xComponentContext)->insertExtensionXcuFile(
                            that->m_eContext == CONTEXT_SHARED, expandUnoRcUrl(url));
                }
            }
            that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
            data.iniEntry = dp_misc::makeRcTerm(url);
            that->addDataToDb(getURL(), data);
        }
    }
    else // revoke
    {
        if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv)) {
            t_string2string_map entries(
                that->m_registeredPackages->getEntries());
            for (t_string2string_map::iterator i(entries.begin());
                 i != entries.end(); ++i)
            {
                //If the xcu file was installed before the configmgr was changed
                //to use the configmgr.ini, one needed to rebuild to whole directory
                //structur containing the xcu, xcs files from all extensions. Now,
                //we just add all other xcu/xcs files to the configmgr.ini instead of
                //rebuilding the directory structure.
                rtl::OUString url2(
                    rtl::OStringToOUString(i->first, RTL_TEXTENCODING_UTF8));
                if (url2 != url) {
                   bool schema = i->second.equalsIgnoreAsciiCase(
                       "vnd.sun.star.configuration-schema");
                   OUString url_replaced(url2);
                   ConfigurationBackendDb::Data data;
                   if (!schema)
                   {
                       const OUString sModFolder = that->createFolder(OUString(), xCmdEnv);
                       bool out_replaced = false;
                       url_replaced = replaceOrigin(
                           url2, sModFolder, xCmdEnv, out_replaced);
                       if (out_replaced)
                           data.dataUrl = sModFolder;
                       else
                           deleteTempFolder(sModFolder);
                   }
                   that->addToConfigmgrIni(schema, true, url_replaced, xCmdEnv);
                   data.iniEntry = dp_misc::makeRcTerm(url_replaced);
                   that->addDataToDb(url2, data);
                }
                that->m_registeredPackages->erase(i->first);
            }
            try
            {
                ::ucbhelper::Content(
                    makeURL( that->getCachePath(), OUSTR("registry") ),
                    xCmdEnv ).executeCommand(
                        OUSTR("delete"), Any( true /* delete physically */ ) );
            }
            catch(Exception&)
            {
                OSL_ASSERT(0);
            }
        }

        ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
        //If an xcu file was life deployed then always a data entry is written.
        //If the xcu file was already in the configmr.ini then there is also
        //a data entry
        if (!m_isSchema && data)
        {
            com::sun::star::configuration::Update::get(
                that->m_xComponentContext)->removeExtensionXcuFile(expandUnoRcTerm(data->iniEntry));
        }
        that->revokeEntryFromDb(url);
    }
}

} // anon namespace

namespace sdecl = comphelper::service_decl;
sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
extern sdecl::ServiceDecl const serviceDecl(
    serviceBI,
    "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
    BACKEND_SERVICE_NAME );

} // namespace configuration
} // namespace backend
} // namespace dp_registry
