Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / desktop / source / deployment / registry / configuration / dp_configuration.cxx
blob40d0ee9c8b3c9d26e1981a9ab9c8ca58c896c770
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 //TODO: Large parts of this file were copied from dp_component.cxx; those parts
21 // should be consolidated.
23 #include <config_extensions.h>
25 #include <dp_backend.h>
26 #if HAVE_FEATURE_EXTENSIONS
27 #include <dp_persmap.h>
28 #endif
29 #include <dp_services.hxx>
30 #include <dp_ucb.h>
31 #include <rtl/string.hxx>
32 #include <rtl/strbuf.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <rtl/uri.hxx>
35 #include <osl/file.hxx>
36 #include <cppuhelper/exc_hlp.hxx>
37 #include <ucbhelper/content.hxx>
38 #include <unotools/ucbhelper.hxx>
39 #include <comphelper/servicedecl.hxx>
40 #include <xmlscript/xml_helper.hxx>
41 #include <comphelper/lok.hxx>
42 #include <svl/inettype.hxx>
43 #include <com/sun/star/configuration/Update.hpp>
44 #include <com/sun/star/ucb/NameClash.hpp>
45 #include <com/sun/star/io/XActiveDataSink.hpp>
46 #include <com/sun/star/lang/IllegalArgumentException.hpp>
47 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
48 #include <com/sun/star/util/XRefreshable.hpp>
49 #include <deque>
50 #include <memory>
51 #include <utility>
53 #include "dp_configurationbackenddb.hxx"
55 using namespace ::dp_misc;
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::ucb;
60 namespace dp_registry {
61 namespace backend {
62 namespace configuration {
63 namespace {
65 class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend
67 class PackageImpl : public ::dp_registry::backend::Package
69 BackendImpl * getMyBackend() const ;
71 const bool m_isSchema;
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 ) 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 ) override;
85 public:
86 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 m_isSchema( isSchema )
96 friend class PackageImpl;
98 std::deque<OUString> m_xcs_files;
99 std::deque<OUString> m_xcu_files;
100 std::deque<OUString> & getFiles( bool xcs ) {
101 return xcs ? m_xcs_files : m_xcu_files;
104 bool m_configmgrini_inited;
105 bool m_configmgrini_modified;
106 std::unique_ptr<ConfigurationBackendDb> m_backendDb;
108 // PackageRegistryBackend
109 virtual Reference<deployment::XPackage> bindPackage_(
110 OUString const & url, OUString const & mediaType, bool bRemoved,
111 OUString const & identifier,
112 Reference<XCommandEnvironment> const & xCmdEnv ) override;
114 #if HAVE_FEATURE_EXTENSIONS
115 // for backwards compatibility - nil if no (compatible) back-compat db present
116 std::unique_ptr<PersistentMap> m_registeredPackages;
117 #endif
119 virtual void SAL_CALL disposing() override;
121 const Reference<deployment::XPackageTypeInfo> m_xConfDataTypeInfo;
122 const Reference<deployment::XPackageTypeInfo> m_xConfSchemaTypeInfo;
123 Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos;
125 void configmgrini_verify_init(
126 Reference<XCommandEnvironment> const & xCmdEnv );
127 void configmgrini_flush( Reference<XCommandEnvironment> const & xCmdEnv );
129 /* The parameter 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.
133 void addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url,
134 Reference<XCommandEnvironment> const & xCmdEnv );
135 #if HAVE_FEATURE_EXTENSIONS
136 bool removeFromConfigmgrIni( bool isSchema, OUString const & url,
137 Reference<XCommandEnvironment> const & xCmdEnv );
138 #endif
139 void addDataToDb(OUString const & url, ConfigurationBackendDb::Data const & data);
140 ::boost::optional<ConfigurationBackendDb::Data> readDataFromDb(OUString const & url);
141 void revokeEntryFromDb(OUString const & url);
142 bool hasActiveEntry(OUString const & url);
143 bool activateEntry(OUString const & url);
145 public:
146 BackendImpl( Sequence<Any> const & args,
147 Reference<XComponentContext> const & xComponentContext );
149 // XPackageRegistry
150 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
151 getSupportedPackageTypes() override;
152 virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) override;
154 using PackageRegistryBackend::disposing;
158 void BackendImpl::disposing()
160 try {
161 configmgrini_flush( Reference<XCommandEnvironment>() );
163 PackageRegistryBackend::disposing();
165 catch (const RuntimeException &) {
166 throw;
168 catch (const Exception &) {
169 Any exc( ::cppu::getCaughtException() );
170 throw lang::WrappedTargetRuntimeException(
171 "caught unexpected exception while disposing...",
172 static_cast<OWeakObject *>(this), exc );
177 BackendImpl::BackendImpl(
178 Sequence<Any> const & args,
179 Reference<XComponentContext> const & xComponentContext )
180 : PackageRegistryBackend( args, xComponentContext ),
181 m_configmgrini_inited( false ),
182 m_configmgrini_modified( false ),
183 m_xConfDataTypeInfo( new Package::TypeInfo(
184 "application/vnd.sun.star.configuration-data",
185 "*.xcu",
186 DpResId(RID_STR_CONF_DATA)
187 ) ),
188 m_xConfSchemaTypeInfo( new Package::TypeInfo(
189 "application/vnd.sun.star.configuration-schema",
190 "*.xcs",
191 DpResId(RID_STR_CONF_SCHEMA)
192 ) ),
193 m_typeInfos( 2 )
195 m_typeInfos[ 0 ] = m_xConfDataTypeInfo;
196 m_typeInfos[ 1 ] = m_xConfSchemaTypeInfo;
198 const Reference<XCommandEnvironment> xCmdEnv;
200 if (transientMode())
202 // TODO
204 else
206 OUString dbFile = makeURL(getCachePath(), "backenddb.xml");
207 m_backendDb.reset(
208 new ConfigurationBackendDb(getComponentContext(), dbFile));
209 //clean up data folders which are no longer used.
210 //This must not be done in the same process where the help files
211 //are still registers. Only after revoking and restarting OOo the folders
212 //can be removed. This works now, because the extension manager is a singleton
213 //and the backends are only create once per process.
214 std::vector<OUString> folders = m_backendDb->getAllDataUrls();
215 deleteUnusedFolders(folders);
217 configmgrini_verify_init( xCmdEnv );
219 #if HAVE_FEATURE_EXTENSIONS
220 std::unique_ptr<PersistentMap> pMap;
221 OUString aCompatURL( makeURL( getCachePath(), "registered_packages.pmap" ) );
223 // Don't create it if it doesn't exist already
224 if ( ::utl::UCBContentHelper::Exists( expandUnoRcUrl( aCompatURL ) ) )
228 pMap.reset( new PersistentMap( aCompatURL ) );
230 catch (const Exception &e)
232 OUString aStr = "Exception loading legacy package database: '" +
233 e.Message +
234 "' - ignoring file, please remove it.\n";
235 dp_misc::writeConsole( aStr.getStr() );
238 m_registeredPackages = std::move(pMap);
239 #endif
243 void BackendImpl::addDataToDb(
244 OUString const & url, ConfigurationBackendDb::Data const & data)
246 if (m_backendDb)
247 m_backendDb->addEntry(url, data);
250 ::boost::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
251 OUString const & url)
253 ::boost::optional<ConfigurationBackendDb::Data> data;
254 if (m_backendDb)
255 data = m_backendDb->getEntry(url);
256 return data;
259 void BackendImpl::revokeEntryFromDb(OUString const & url)
261 if (m_backendDb)
262 m_backendDb->revokeEntry(url);
265 bool BackendImpl::hasActiveEntry(OUString const & url)
267 if (m_backendDb)
268 return m_backendDb->hasActiveEntry(url);
269 return false;
272 bool BackendImpl::activateEntry(OUString const & url)
274 if (m_backendDb)
275 return m_backendDb->activateEntry(url);
276 return false;
280 // XPackageRegistry
282 Sequence< Reference<deployment::XPackageTypeInfo> >
283 BackendImpl::getSupportedPackageTypes()
285 return m_typeInfos;
287 void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/)
289 if (m_backendDb)
290 m_backendDb->removeEntry(url);
293 // PackageRegistryBackend
295 Reference<deployment::XPackage> BackendImpl::bindPackage_(
296 OUString const & url, OUString const & mediaType_,
297 bool bRemoved, OUString const & identifier,
298 Reference<XCommandEnvironment> const & xCmdEnv )
300 OUString mediaType( mediaType_ );
301 if (mediaType.isEmpty())
303 // detect media-type:
304 ::ucbhelper::Content ucbContent;
305 if (create_ucb_content( &ucbContent, url, xCmdEnv ))
307 const OUString title( StrTitle::getTitle( ucbContent ) );
308 if (title.endsWithIgnoreAsciiCase( ".xcu" )) {
309 mediaType = "application/vnd.sun.star.configuration-data";
311 if (title.endsWithIgnoreAsciiCase( ".xcs" )) {
312 mediaType = "application/vnd.sun.star.configuration-schema";
315 if (mediaType.isEmpty())
316 throw lang::IllegalArgumentException(
317 StrCannotDetectMediaType() + url,
318 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) );
321 OUString type, subType;
322 INetContentTypeParameterList params;
323 if (INetContentTypes::parse( mediaType, type, subType, &params ))
325 if (type.equalsIgnoreAsciiCase("application"))
327 OUString name;
328 if (!bRemoved)
330 ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
331 name = StrTitle::getTitle( ucbContent );
334 ::ucbhelper::Content ucbContent( url, xCmdEnv, m_xComponentContext );
335 if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-data"))
337 return new PackageImpl(
338 this, url, name, m_xConfDataTypeInfo, false /* data file */,
339 bRemoved, identifier);
341 else if (subType.equalsIgnoreAsciiCase( "vnd.sun.star.configuration-schema")) {
342 return new PackageImpl(
343 this, url, name, m_xConfSchemaTypeInfo, true /* schema file */,
344 bRemoved, identifier);
348 throw lang::IllegalArgumentException(
349 StrUnsupportedMediaType() + mediaType,
350 static_cast<OWeakObject *>(this),
351 static_cast<sal_Int16>(-1) );
355 void BackendImpl::configmgrini_verify_init(
356 Reference<XCommandEnvironment> const & xCmdEnv )
358 if (transientMode())
359 return;
360 const ::osl::MutexGuard guard( getMutex() );
361 if (! m_configmgrini_inited)
363 // common rc:
364 ::ucbhelper::Content ucb_content;
365 if (create_ucb_content(
366 &ucb_content,
367 makeURL( getCachePath(), "configmgr.ini" ),
368 xCmdEnv, false /* no throw */ ))
370 OUString line;
371 if (readLine( &line, "SCHEMA=", ucb_content,
372 RTL_TEXTENCODING_UTF8 ))
374 sal_Int32 index = RTL_CONSTASCII_LENGTH("SCHEMA=");
375 do {
376 OUString token( line.getToken( 0, ' ', index ).trim() );
377 if (!token.isEmpty()) {
378 //The file may not exist anymore if a shared or bundled
379 //extension was removed, but it can still be in the configmgrini.
380 //After running XExtensionManager::synchronize, the configmgrini is
381 //cleaned up
382 m_xcs_files.push_back( token );
385 while (index >= 0);
387 if (readLine( &line, "DATA=", ucb_content,
388 RTL_TEXTENCODING_UTF8 )) {
389 sal_Int32 index = RTL_CONSTASCII_LENGTH("DATA=");
390 do {
391 OUString token( line.getToken( 0, ' ', index ).trim() );
392 if (!token.isEmpty())
394 if (token[ 0 ] == '?')
395 token = token.copy( 1 );
396 //The file may not exist anymore if a shared or bundled
397 //extension was removed, but it can still be in the configmgrini.
398 //After running XExtensionManager::synchronize, the configmgrini is
399 //cleaned up
400 m_xcu_files.push_back( token );
403 while (index >= 0);
406 m_configmgrini_modified = false;
407 m_configmgrini_inited = true;
412 void BackendImpl::configmgrini_flush(
413 Reference<XCommandEnvironment> const & xCmdEnv )
415 if (transientMode())
416 return;
417 if (!m_configmgrini_inited || !m_configmgrini_modified)
418 return;
420 OStringBuffer buf;
421 if (! m_xcs_files.empty())
423 auto iPos( m_xcs_files.cbegin() );
424 auto const iEnd( m_xcs_files.cend() );
425 buf.append( "SCHEMA=" );
426 while (iPos != iEnd) {
427 // encoded ASCII file-urls:
428 const OString item(
429 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
430 buf.append( item );
431 ++iPos;
432 if (iPos != iEnd)
433 buf.append( ' ' );
435 buf.append(LF);
437 if (! m_xcu_files.empty())
439 auto iPos( m_xcu_files.cbegin() );
440 auto const iEnd( m_xcu_files.cend() );
441 buf.append( "DATA=" );
442 while (iPos != iEnd) {
443 // encoded ASCII file-urls:
444 const OString item(
445 OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) );
446 buf.append( item );
447 ++iPos;
448 if (iPos != iEnd)
449 buf.append( ' ' );
451 buf.append(LF);
454 // write configmgr.ini:
455 const Reference<io::XInputStream> xData(
456 ::xmlscript::createInputStream(
457 reinterpret_cast<sal_Int8 const *>(buf.getStr()),
458 buf.getLength() ) );
459 ::ucbhelper::Content ucb_content(
460 makeURL( getCachePath(), "configmgr.ini" ), xCmdEnv, m_xComponentContext );
461 ucb_content.writeStream( xData, true /* replace existing */ );
463 m_configmgrini_modified = false;
467 void BackendImpl::addToConfigmgrIni( bool isSchema, bool isURL, OUString const & url_,
468 Reference<XCommandEnvironment> const & xCmdEnv )
470 const OUString rcterm( isURL ? dp_misc::makeRcTerm(url_) : url_ );
471 const ::osl::MutexGuard guard( getMutex() );
472 configmgrini_verify_init( xCmdEnv );
473 std::deque<OUString> & rSet = getFiles(isSchema);
474 if (std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) {
475 rSet.push_front( rcterm ); // prepend to list, thus overriding
476 // write immediately:
477 m_configmgrini_modified = true;
478 configmgrini_flush( xCmdEnv );
482 #if HAVE_FEATURE_EXTENSIONS
483 bool BackendImpl::removeFromConfigmgrIni(
484 bool isSchema, OUString const & url_,
485 Reference<XCommandEnvironment> const & xCmdEnv )
487 const OUString rcterm( dp_misc::makeRcTerm(url_) );
488 const ::osl::MutexGuard guard( getMutex() );
489 configmgrini_verify_init( xCmdEnv );
490 std::deque<OUString> & rSet = getFiles(isSchema);
491 auto i(std::find(rSet.begin(), rSet.end(), rcterm));
492 if (i == rSet.end() && !isSchema)
494 //in case the xcu contained %origin% then the configmr.ini contains the
495 //url to the file in the user installation (e.g. $BUNDLED_EXTENSIONS_USER)
496 //However, m_url (getURL()) contains the URL for the file in the actual
497 //extension installation.
498 ::boost::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
499 if (data)
500 i = std::find(rSet.begin(), rSet.end(), data->iniEntry);
502 if (i == rSet.end()) {
503 return false;
505 rSet.erase(i);
506 // write immediately:
507 m_configmgrini_modified = true;
508 configmgrini_flush( xCmdEnv );
509 return true;
511 #endif
513 // Package
516 BackendImpl * BackendImpl::PackageImpl::getMyBackend() const
518 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get());
519 if (nullptr == pBackend)
521 //May throw a DisposedException
522 check();
523 //We should never get here...
524 throw RuntimeException(
525 "Failed to get the BackendImpl",
526 static_cast<OWeakObject*>(const_cast<PackageImpl *>(this)));
528 return pBackend;
531 beans::Optional< beans::Ambiguous<sal_Bool> >
532 BackendImpl::PackageImpl::isRegistered_(
533 ::osl::ResettableMutexGuard &,
534 ::rtl::Reference<AbortChannel> const &,
535 Reference<XCommandEnvironment> const & )
537 BackendImpl * that = getMyBackend();
539 bool bReg = false;
540 if (that->hasActiveEntry(getURL()))
541 bReg = true;
543 #if HAVE_FEATURE_EXTENSIONS
544 const OUString url(getURL());
545 if (!bReg && that->m_registeredPackages.get())
547 // fallback for user extension registered in berkeley DB
548 bReg = that->m_registeredPackages->has(
549 OUStringToOString( url, RTL_TEXTENCODING_UTF8 ));
551 #endif
552 return beans::Optional< beans::Ambiguous<sal_Bool> >(
553 true, beans::Ambiguous<sal_Bool>( bReg, false ) );
557 OUString encodeForXml( OUString const & text )
559 // encode conforming xml:
560 sal_Int32 len = text.getLength();
561 OUStringBuffer buf;
562 for ( sal_Int32 pos = 0; pos < len; ++pos )
564 sal_Unicode c = text[ pos ];
565 switch (c) {
566 case '<':
567 buf.append( "&lt;" );
568 break;
569 case '>':
570 buf.append( "&gt;" );
571 break;
572 case '&':
573 buf.append( "&amp;" );
574 break;
575 case '\'':
576 buf.append( "&apos;" );
577 break;
578 case '\"':
579 buf.append( "&quot;" );
580 break;
581 default:
582 buf.append( c );
583 break;
586 return buf.makeStringAndClear();
590 OUString replaceOrigin(
591 OUString const & url, OUString const & destFolder, Reference< XCommandEnvironment > const & xCmdEnv, Reference< XComponentContext > const & xContext, bool & out_replaced)
593 // looking for %origin%:
594 ::ucbhelper::Content ucb_content( url, xCmdEnv, xContext );
595 std::vector<sal_Int8> bytes( readFile( ucb_content ) );
596 std::vector<sal_Int8> filtered( bytes.size() * 2 );
597 bool use_filtered = false;
598 OString origin;
599 sal_Char const * pBytes = reinterpret_cast<sal_Char const *>(
600 bytes.data());
601 std::size_t nBytes = bytes.size();
602 size_t write_pos = 0;
603 while (nBytes > 0)
605 sal_Int32 index = rtl_str_indexOfChar_WithLength( pBytes, nBytes, '%' );
606 if (index < 0) {
607 if (! use_filtered) // opt
608 break;
609 index = nBytes;
612 if ((write_pos + index) > filtered.size())
613 filtered.resize( (filtered.size() + index) * 2 );
614 memcpy( filtered.data() + write_pos, pBytes, index );
615 write_pos += index;
616 pBytes += index;
617 nBytes -= index;
618 if (nBytes == 0)
619 break;
621 // consume %:
622 ++pBytes;
623 --nBytes;
624 sal_Char const * pAdd = "%";
625 sal_Int32 nAdd = 1;
626 if (nBytes > 1 && pBytes[ 0 ] == '%')
628 // %% => %
629 ++pBytes;
630 --nBytes;
631 use_filtered = true;
633 else if (rtl_str_shortenedCompare_WithLength(
634 pBytes, nBytes,
635 "origin%",
636 RTL_CONSTASCII_LENGTH("origin%"),
637 RTL_CONSTASCII_LENGTH("origin%")) == 0)
639 if (origin.isEmpty()) {
640 // encode only once
641 origin = OUStringToOString(
642 encodeForXml( url.copy( 0, url.lastIndexOf( '/' ) ) ),
643 // xxx todo: encode always for UTF-8? => lookup doc-header?
644 RTL_TEXTENCODING_UTF8 );
646 pAdd = origin.getStr();
647 nAdd = origin.getLength();
648 pBytes += RTL_CONSTASCII_LENGTH("origin%");
649 nBytes -= RTL_CONSTASCII_LENGTH("origin%");
650 use_filtered = true;
652 if ((write_pos + nAdd) > filtered.size())
653 filtered.resize( (filtered.size() + nAdd) * 2 );
654 memcpy( filtered.data() + write_pos, pAdd, nAdd );
655 write_pos += nAdd;
657 if (!use_filtered)
658 return url;
659 if (write_pos < filtered.size())
660 filtered.resize( write_pos );
661 OUString newUrl(url);
662 if (!destFolder.isEmpty())
664 //get the file name of the xcu and add it to the url of the temporary folder
665 sal_Int32 i = url.lastIndexOf('/');
666 newUrl = destFolder + url.copy(i);
669 ucbhelper::Content(newUrl, xCmdEnv, xContext).writeStream(
670 xmlscript::createInputStream(filtered), true);
671 out_replaced = true;
672 return newUrl;
676 void BackendImpl::PackageImpl::processPackage_(
677 ::osl::ResettableMutexGuard &,
678 bool doRegisterPackage,
679 bool startup,
680 ::rtl::Reference<AbortChannel> const &,
681 Reference<XCommandEnvironment> const & xCmdEnv )
683 BackendImpl * that = getMyBackend();
684 OUString url( getURL() );
686 if (doRegisterPackage)
688 if (getMyBackend()->activateEntry(getURL()))
690 ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
691 OSL_ASSERT(data);
692 that->addToConfigmgrIni( m_isSchema, false, data->iniEntry, xCmdEnv );
694 else
696 ConfigurationBackendDb::Data data;
697 if (!m_isSchema)
699 const OUString sModFolder = that->createFolder(xCmdEnv);
700 bool out_replaced = false;
701 url = replaceOrigin(url, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
702 if (out_replaced)
703 data.dataUrl = sModFolder;
704 else
705 deleteTempFolder(sModFolder);
707 //No need for live-deployment for bundled extension, because OOo
708 //restarts after installation
709 if ((that->m_eContext != Context::Bundled && !startup)
710 || comphelper::LibreOfficeKit::isActive())
712 if (m_isSchema)
714 css::configuration::Update::get(
715 that->m_xComponentContext)->insertExtensionXcsFile(
716 that->m_eContext == Context::Shared, expandUnoRcUrl(url));
718 else
720 css::configuration::Update::get(
721 that->m_xComponentContext)->insertExtensionXcuFile(
722 that->m_eContext == Context::Shared, expandUnoRcUrl(url));
725 that->addToConfigmgrIni( m_isSchema, true, url, xCmdEnv );
726 data.iniEntry = dp_misc::makeRcTerm(url);
727 that->addDataToDb(getURL(), data);
730 else // revoke
732 #if HAVE_FEATURE_EXTENSIONS
733 if (!that->removeFromConfigmgrIni(m_isSchema, url, xCmdEnv) &&
734 that->m_registeredPackages.get()) {
735 // Obsolete package database handling - should be removed for LibreOffice 4.0
736 t_string2string_map entries(
737 that->m_registeredPackages->getEntries());
738 for (auto const& entry : entries)
740 //If the xcu file was installed before the configmgr was changed
741 //to use the configmgr.ini, one needed to rebuild to whole directory
742 //structure containing the xcu, xcs files from all extensions. Now,
743 //we just add all other xcu/xcs files to the configmgr.ini instead of
744 //rebuilding the directory structure.
745 OUString url2(
746 OStringToOUString(entry.first, RTL_TEXTENCODING_UTF8));
747 if (url2 != url) {
748 bool schema = entry.second.equalsIgnoreAsciiCase(
749 "vnd.sun.star.configuration-schema");
750 OUString url_replaced(url2);
751 ConfigurationBackendDb::Data data;
752 if (!schema)
754 const OUString sModFolder = that->createFolder(xCmdEnv);
755 bool out_replaced = false;
756 url_replaced = replaceOrigin(
757 url2, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
758 if (out_replaced)
759 data.dataUrl = sModFolder;
760 else
761 deleteTempFolder(sModFolder);
763 that->addToConfigmgrIni(schema, true, url_replaced, xCmdEnv);
764 data.iniEntry = dp_misc::makeRcTerm(url_replaced);
765 that->addDataToDb(url2, data);
767 that->m_registeredPackages->erase(entry.first);
771 ::ucbhelper::Content(
772 makeURL( that->getCachePath(), "registry" ),
773 xCmdEnv, that->getComponentContext() ).executeCommand(
774 "delete", Any( true /* delete physically */ ) );
776 catch(const Exception&)
778 OSL_ASSERT(false);
781 #endif
782 ::boost::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
783 //If an xcu file was life deployed then always a data entry is written.
784 //If the xcu file was already in the configmr.ini then there is also
785 //a data entry
786 if (!m_isSchema && data)
788 css::configuration::Update::get(
789 that->m_xComponentContext)->removeExtensionXcuFile(expandUnoRcTerm(data->iniEntry));
791 that->revokeEntryFromDb(url);
795 } // anon namespace
797 namespace sdecl = comphelper::service_decl;
798 sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI;
799 sdecl::ServiceDecl const serviceDecl(
800 serviceBI,
801 "com.sun.star.comp.deployment.configuration.PackageRegistryBackend",
802 BACKEND_SERVICE_NAME );
804 } // namespace configuration
805 } // namespace backend
806 } // namespace dp_registry
808 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */