23#include <config_extensions.h>
26#if HAVE_FEATURE_EXTENSIONS
31#include <rtl/string.hxx>
32#include <rtl/strbuf.hxx>
33#include <rtl/ustrbuf.hxx>
43#include <com/sun/star/configuration/Update.hpp>
44#include <com/sun/star/lang/IllegalArgumentException.hpp>
45#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
65 BackendImpl * getMyBackend()
const ;
70 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
71 ::osl::ResettableMutexGuard & guard,
73 Reference<XCommandEnvironment>
const & xCmdEnv )
override;
74 virtual void processPackage_(
75 ::osl::ResettableMutexGuard & guard,
79 Reference<XCommandEnvironment>
const & xCmdEnv )
override;
84 OUString
const & url, OUString
const & name,
85 Reference<deployment::XPackageTypeInfo>
const & xPackageType,
86 bool isSchema,
bool bRemoved, OUString
const & identifier)
92 friend class PackageImpl;
96 std::deque<OUString> & getFiles(
bool xcs ) {
105 virtual Reference<deployment::XPackage> bindPackage_(
106 OUString
const & url, OUString
const & mediaType,
bool bRemoved,
107 OUString
const & identifier,
108 Reference<XCommandEnvironment>
const & xCmdEnv )
override;
110#if HAVE_FEATURE_EXTENSIONS
112 std::unique_ptr<PersistentMap> m_registeredPackages;
115 virtual void SAL_CALL disposing()
override;
121 void configmgrini_verify_init(
122 Reference<XCommandEnvironment>
const & xCmdEnv );
123 void configmgrini_flush( Reference<XCommandEnvironment>
const & xCmdEnv );
129 void addToConfigmgrIni(
bool isSchema,
bool isURL, OUString
const & url,
130 Reference<XCommandEnvironment>
const & xCmdEnv );
131#if HAVE_FEATURE_EXTENSIONS
132 bool removeFromConfigmgrIni(
bool isSchema, OUString
const & url,
133 Reference<XCommandEnvironment>
const & xCmdEnv );
135 void addDataToDb(OUString
const & url, ConfigurationBackendDb::Data
const & data);
136 ::std::optional<ConfigurationBackendDb::Data> readDataFromDb(std::u16string_view url);
137 void revokeEntryFromDb(std::u16string_view url);
138 bool hasActiveEntry(std::u16string_view url);
139 bool activateEntry(std::u16string_view url);
142 BackendImpl( Sequence<Any>
const & args,
143 Reference<XComponentContext>
const & xComponentContext );
151 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
152 getSupportedPackageTypes()
override;
153 virtual void SAL_CALL packageRemoved(OUString
const & url, OUString
const & mediaType)
override;
159void BackendImpl::disposing()
162 configmgrini_flush( Reference<XCommandEnvironment>() );
169 catch (
const Exception &) {
170 Any exc( ::cppu::getCaughtException() );
171 throw lang::WrappedTargetRuntimeException(
172 "caught unexpected exception while disposing...",
173 static_cast<OWeakObject *
>(
this), exc );
178BackendImpl::BackendImpl(
179 Sequence<Any>
const & args,
180 Reference<XComponentContext>
const & xComponentContext )
181 : PackageRegistryBackend(
args, xComponentContext ),
185 "application/vnd.sun.star.configuration-data",
190 "application/vnd.sun.star.configuration-schema",
196 const Reference<XCommandEnvironment> xCmdEnv;
204 OUString dbFile =
makeURL(getCachePath(),
"backenddb.xml");
212 std::vector<OUString> folders =
m_backendDb->getAllDataUrls();
213 deleteUnusedFolders(folders);
215 configmgrini_verify_init( xCmdEnv );
217#if HAVE_FEATURE_EXTENSIONS
218 std::unique_ptr<PersistentMap> pMap;
219 OUString aCompatURL(
makeURL( getCachePath(),
"registered_packages.pmap" ) );
222 if ( ::utl::UCBContentHelper::Exists(
expandUnoRcUrl( aCompatURL ) ) )
226 pMap.reset(
new PersistentMap( aCompatURL ) );
228 catch (
const Exception &e)
230 OUString
aStr =
"Exception loading legacy package database: '" +
232 "' - ignoring file, please remove it.\n";
236 m_registeredPackages = std::move(pMap);
242OUString BackendImpl::getImplementationName()
244 return "com.sun.star.comp.deployment.configuration.PackageRegistryBackend";
247sal_Bool BackendImpl::supportsService(
const OUString& ServiceName )
252css::uno::Sequence< OUString > BackendImpl::getSupportedServiceNames()
257void BackendImpl::addDataToDb(
258 OUString
const & url, ConfigurationBackendDb::Data
const & data)
264::std::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
265 std::u16string_view url)
267 ::std::optional<ConfigurationBackendDb::Data> data;
273void BackendImpl::revokeEntryFromDb(std::u16string_view url)
279bool BackendImpl::hasActiveEntry(std::u16string_view url)
286bool BackendImpl::activateEntry(std::u16string_view url)
296Sequence< Reference<deployment::XPackageTypeInfo> >
297BackendImpl::getSupportedPackageTypes()
301void BackendImpl::packageRemoved(OUString
const & url, OUString
const & )
309Reference<deployment::XPackage> BackendImpl::bindPackage_(
310 OUString
const & url, OUString
const & mediaType_,
311 bool bRemoved, OUString
const & identifier,
312 Reference<XCommandEnvironment>
const & xCmdEnv )
314 OUString mediaType( mediaType_ );
315 if (mediaType.isEmpty())
321 const OUString title( StrTitle::getTitle( ucbContent ) );
322 if (title.endsWithIgnoreAsciiCase(
".xcu" )) {
323 mediaType =
"application/vnd.sun.star.configuration-data";
325 if (title.endsWithIgnoreAsciiCase(
".xcs" )) {
326 mediaType =
"application/vnd.sun.star.configuration-schema";
329 if (mediaType.isEmpty())
330 throw lang::IllegalArgumentException(
331 StrCannotDetectMediaType() + url,
332 static_cast<OWeakObject *
>(
this),
static_cast<sal_Int16
>(-1) );
335 OUString
type, subType;
339 if (
type.equalsIgnoreAsciiCase(
"application"))
345 name = StrTitle::getTitle( ucbContent );
348 if (subType.equalsIgnoreAsciiCase(
"vnd.sun.star.configuration-data"))
350 return new PackageImpl(
352 bRemoved, identifier);
354 else if (subType.equalsIgnoreAsciiCase(
"vnd.sun.star.configuration-schema")) {
355 return new PackageImpl(
357 bRemoved, identifier);
361 throw lang::IllegalArgumentException(
362 StrUnsupportedMediaType() + mediaType,
363 static_cast<OWeakObject *
>(
this),
364 static_cast<sal_Int16
>(-1) );
368void BackendImpl::configmgrini_verify_init(
369 Reference<XCommandEnvironment>
const & xCmdEnv )
373 const ::osl::MutexGuard guard( m_aMutex );
381 makeURL( getCachePath(),
"configmgr.ini" ),
385 if (
readLine( &line, u
"SCHEMA=", ucb_content,
386 RTL_TEXTENCODING_UTF8 ))
388 sal_Int32
index = RTL_CONSTASCII_LENGTH(
"SCHEMA=");
391 if (!token.isEmpty()) {
401 if (
readLine( &line, u
"DATA=", ucb_content,
402 RTL_TEXTENCODING_UTF8 )) {
403 sal_Int32
index = RTL_CONSTASCII_LENGTH(
"DATA=");
408 if (token[ 0 ] ==
'?')
409 token = token.substr( 1 );
425void BackendImpl::configmgrini_flush(
426 Reference<XCommandEnvironment>
const & xCmdEnv )
438 buf.append(
"SCHEMA=" );
439 while (iPos != iEnd) {
454 buf.append(
"DATA=" );
455 while (iPos != iEnd) {
468 const Reference<io::XInputStream> xData(
469 ::xmlscript::createInputStream(
470 reinterpret_cast<sal_Int8 const *
>(buf.getStr()),
480void BackendImpl::addToConfigmgrIni(
bool isSchema,
bool isURL, OUString
const & url_,
481 Reference<XCommandEnvironment>
const & xCmdEnv )
484 const ::osl::MutexGuard guard( m_aMutex );
485 configmgrini_verify_init( xCmdEnv );
486 std::deque<OUString> &
rSet = getFiles(isSchema);
487 if (std::find(
rSet.begin(),
rSet.end(), rcterm ) ==
rSet.end()) {
488 rSet.push_front( rcterm );
491 configmgrini_flush( xCmdEnv );
495#if HAVE_FEATURE_EXTENSIONS
496bool BackendImpl::removeFromConfigmgrIni(
497 bool isSchema, OUString
const & url_,
498 Reference<XCommandEnvironment>
const & xCmdEnv )
501 const ::osl::MutexGuard guard( m_aMutex );
502 configmgrini_verify_init( xCmdEnv );
503 std::deque<OUString> &
rSet = getFiles(isSchema);
504 auto i(std::find(
rSet.begin(),
rSet.end(), rcterm));
505 if (i ==
rSet.end() && !isSchema)
511 ::std::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
513 i = std::find(
rSet.begin(),
rSet.end(), data->iniEntry);
515 if (i ==
rSet.end()) {
521 configmgrini_flush( xCmdEnv );
529BackendImpl * BackendImpl::PackageImpl::getMyBackend()
const
531 BackendImpl * pBackend =
static_cast<BackendImpl *
>(m_myBackend.get());
532 if (
nullptr == pBackend)
538 "Failed to get the BackendImpl",
539 static_cast<OWeakObject*
>(
const_cast<PackageImpl *
>(
this)));
544beans::Optional< beans::Ambiguous<sal_Bool> >
545BackendImpl::PackageImpl::isRegistered_(
546 ::osl::ResettableMutexGuard &,
548 Reference<XCommandEnvironment>
const & )
550 BackendImpl * that = getMyBackend();
553 if (that->hasActiveEntry(getURL()))
556#if HAVE_FEATURE_EXTENSIONS
557 const OUString url(getURL());
558 if (!bReg && that->m_registeredPackages)
561 bReg = that->m_registeredPackages->has(
565 return beans::Optional< beans::Ambiguous<sal_Bool> >(
566 true, beans::Ambiguous<sal_Bool>( bReg,
false ) );
570OUString replaceOrigin(
571 OUString
const & url, std::u16string_view destFolder, Reference< XCommandEnvironment >
const & xCmdEnv, Reference< XComponentContext >
const &
xContext,
bool & out_replaced)
576 std::vector<sal_Int8> filtered(
bytes.size() * 2 );
577 bool use_filtered =
false;
579 char const * pBytes =
reinterpret_cast<char const *
>(
581 std::size_t nBytes =
bytes.size();
582 size_t write_pos = 0;
585 sal_Int32
index = rtl_str_indexOfChar_WithLength( pBytes, nBytes,
'%' );
592 if ((write_pos + index) > filtered.size())
593 filtered.resize( (filtered.size() + index) * 2 );
594 memcpy( filtered.data() + write_pos, pBytes, index );
604 char const * pAdd =
"%";
606 if (nBytes > 1 && pBytes[ 0 ] ==
'%')
613 else if (rtl_str_shortenedCompare_WithLength(
616 RTL_CONSTASCII_LENGTH(
"origin%"),
617 RTL_CONSTASCII_LENGTH(
"origin%")) == 0)
619 if (origin.isEmpty()) {
624 RTL_TEXTENCODING_UTF8 );
626 pAdd = origin.getStr();
627 nAdd = origin.getLength();
628 pBytes += RTL_CONSTASCII_LENGTH(
"origin%");
629 nBytes -= RTL_CONSTASCII_LENGTH(
"origin%");
632 if ((write_pos + nAdd) > filtered.size())
633 filtered.resize( (filtered.size() + nAdd) * 2 );
634 memcpy( filtered.data() + write_pos, pAdd, nAdd );
639 if (write_pos < filtered.size())
640 filtered.resize( write_pos );
641 OUString newUrl(url);
642 if (!destFolder.empty())
645 sal_Int32
i = url.lastIndexOf(
'/');
646 newUrl = OUString::Concat(destFolder) + url.subView(i);
656void BackendImpl::PackageImpl::processPackage_(
657 ::osl::ResettableMutexGuard &,
658 bool doRegisterPackage,
661 Reference<XCommandEnvironment>
const & xCmdEnv )
663 BackendImpl * that = getMyBackend();
664 OUString url( getURL() );
666 if (doRegisterPackage)
668 if (getMyBackend()->activateEntry(getURL()))
670 ::std::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
672 that->addToConfigmgrIni(
m_isSchema,
false, data->iniEntry, xCmdEnv );
676 ConfigurationBackendDb::Data data;
679 const OUString sModFolder = that->createFolder(xCmdEnv);
680 bool out_replaced =
false;
681 url = replaceOrigin(url, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
683 data.dataUrl = sModFolder;
685 deleteTempFolder(sModFolder);
689 if ((that->m_eContext != Context::Bundled && !startup)
694 css::configuration::Update::get(
695 that->m_xComponentContext)->insertExtensionXcsFile(
700 css::configuration::Update::get(
701 that->m_xComponentContext)->insertExtensionXcuFile(
705 that->addToConfigmgrIni(
m_isSchema,
true, url, xCmdEnv );
707 that->addDataToDb(getURL(), data);
712#if HAVE_FEATURE_EXTENSIONS
713 if (!that->removeFromConfigmgrIni(
m_isSchema, url, xCmdEnv) &&
714 that->m_registeredPackages) {
717 that->m_registeredPackages->getEntries());
718 for (
auto const& entry : entries)
726 OStringToOUString(entry.first, RTL_TEXTENCODING_UTF8));
728 bool schema = entry.second.equalsIgnoreAsciiCase(
729 "vnd.sun.star.configuration-schema");
730 OUString url_replaced(url2);
731 ConfigurationBackendDb::Data data;
734 const OUString sModFolder = that->createFolder(xCmdEnv);
735 bool out_replaced =
false;
736 url_replaced = replaceOrigin(
737 url2, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
739 data.dataUrl = sModFolder;
741 deleteTempFolder(sModFolder);
743 that->addToConfigmgrIni(schema,
true, url_replaced, xCmdEnv);
745 that->addDataToDb(url2, data);
747 that->m_registeredPackages->erase(entry.first);
752 makeURL( that->getCachePath(),
"registry" ),
754 "delete",
Any(
true ) );
756 catch(
const Exception&)
762 ::std::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
768 css::configuration::Update::get(
769 that->m_xComponentContext)->removeExtensionXcuFile(
expandUnoRcTerm(data->iniEntry));
771 that->revokeEntryFromDb(url);
779extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
781 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any>
const& args)
783 return cppu::acquire(
new dp_registry::backend::configuration::BackendImpl(
args, context));
static bool parse(OUString const &rMediaType, OUString &rType, OUString &rSubType, INetContentTypeParameterList *pParameters=nullptr)
virtual void SAL_CALL disposing() override
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)
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)
std::unordered_map< OString, INetContentTypeParameter > INetContentTypeParameterList
static uno::Reference< css::uno::XComponentContext > xContext
OUString encodeForXml(std::u16string_view rStr)
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.
OUString makeRcTerm(OUString const &url)
OUString expandUnoRcUrl(OUString const &url)
std::unordered_map< OString, OString > t_string2string_map
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)
OUString expandUnoRcTerm(OUString const &term_)
DESKTOP_DEPLOYMENTMISC_DLLPUBLIC std::vector< sal_Int8 > readFile(::ucbhelper::Content &ucb_content)
void writeConsole(std::u16string_view sText)
writes the argument string to the console.
constexpr OUStringLiteral BACKEND_SERVICE_NAME
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)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::vector< sal_uInt8 > bytes
Reference< io::XInputStream > createInputStream(std::vector< sal_Int8 > &&rInData)
::boost::spirit::classic::rule< ScannerT > identifier