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