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>
42#include <com/sun/star/configuration/Update.hpp>
43#include <com/sun/star/lang/IllegalArgumentException.hpp>
44#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
64 BackendImpl * getMyBackend()
const ;
69 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_(
70 ::osl::ResettableMutexGuard & guard,
72 Reference<XCommandEnvironment>
const & xCmdEnv )
override;
73 virtual void processPackage_(
74 ::osl::ResettableMutexGuard & guard,
78 Reference<XCommandEnvironment>
const & xCmdEnv )
override;
83 OUString
const & url, OUString
const & name,
84 Reference<deployment::XPackageTypeInfo>
const & xPackageType,
85 bool isSchema,
bool bRemoved, OUString
const & identifier)
91 friend class PackageImpl;
95 std::deque<OUString> & getFiles(
bool xcs ) {
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;
109#if HAVE_FEATURE_EXTENSIONS
111 std::unique_ptr<PersistentMap> m_registeredPackages;
114 virtual void SAL_CALL disposing()
override;
120 void configmgrini_verify_init(
121 Reference<XCommandEnvironment>
const & xCmdEnv );
122 void configmgrini_flush( Reference<XCommandEnvironment>
const & xCmdEnv );
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 );
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);
141 BackendImpl( Sequence<Any>
const & args,
142 Reference<XComponentContext>
const & xComponentContext );
150 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL
151 getSupportedPackageTypes()
override;
152 virtual void SAL_CALL packageRemoved(OUString
const & url, OUString
const & mediaType)
override;
158void BackendImpl::disposing()
161 configmgrini_flush( Reference<XCommandEnvironment>() );
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 );
177BackendImpl::BackendImpl(
178 Sequence<Any>
const & args,
179 Reference<XComponentContext>
const & xComponentContext )
180 : PackageRegistryBackend(
args, xComponentContext ),
184 "application/vnd.sun.star.configuration-data",
189 "application/vnd.sun.star.configuration-schema",
195 const Reference<XCommandEnvironment> xCmdEnv;
203 OUString dbFile =
makeURL(getCachePath(),
"backenddb.xml");
211 std::vector<OUString> folders =
m_backendDb->getAllDataUrls();
212 deleteUnusedFolders(folders);
214 configmgrini_verify_init( xCmdEnv );
216#if HAVE_FEATURE_EXTENSIONS
217 std::unique_ptr<PersistentMap> pMap;
218 OUString aCompatURL(
makeURL( getCachePath(),
"registered_packages.pmap" ) );
221 if ( ::utl::UCBContentHelper::Exists(
expandUnoRcUrl( aCompatURL ) ) )
225 pMap.reset(
new PersistentMap( aCompatURL ) );
227 catch (
const Exception &e)
229 OUString
aStr =
"Exception loading legacy package database: '" +
231 "' - ignoring file, please remove it.\n";
235 m_registeredPackages = std::move(pMap);
241OUString BackendImpl::getImplementationName()
243 return "com.sun.star.comp.deployment.configuration.PackageRegistryBackend";
246sal_Bool BackendImpl::supportsService(
const OUString& ServiceName )
251css::uno::Sequence< OUString > BackendImpl::getSupportedServiceNames()
256void BackendImpl::addDataToDb(
257 OUString
const & url, ConfigurationBackendDb::Data
const & data)
263::std::optional<ConfigurationBackendDb::Data> BackendImpl::readDataFromDb(
264 std::u16string_view url)
266 ::std::optional<ConfigurationBackendDb::Data> data;
272void BackendImpl::revokeEntryFromDb(std::u16string_view url)
278bool BackendImpl::hasActiveEntry(std::u16string_view url)
285bool BackendImpl::activateEntry(std::u16string_view url)
295Sequence< Reference<deployment::XPackageTypeInfo> >
296BackendImpl::getSupportedPackageTypes()
300void BackendImpl::packageRemoved(OUString
const & url, OUString
const & )
308Reference<deployment::XPackage> BackendImpl::bindPackage_(
309 OUString
const & url, OUString
const & mediaType_,
310 bool bRemoved, OUString
const & identifier,
311 Reference<XCommandEnvironment>
const & xCmdEnv )
313 OUString mediaType( mediaType_ );
314 if (mediaType.isEmpty())
320 const OUString title( StrTitle::getTitle( ucbContent ) );
321 if (title.endsWithIgnoreAsciiCase(
".xcu" )) {
322 mediaType =
"application/vnd.sun.star.configuration-data";
324 if (title.endsWithIgnoreAsciiCase(
".xcs" )) {
325 mediaType =
"application/vnd.sun.star.configuration-schema";
328 if (mediaType.isEmpty())
329 throw lang::IllegalArgumentException(
330 StrCannotDetectMediaType() + url,
331 static_cast<OWeakObject *
>(
this),
static_cast<sal_Int16
>(-1) );
334 OUString
type, subType;
338 if (
type.equalsIgnoreAsciiCase(
"application"))
344 name = StrTitle::getTitle( ucbContent );
347 if (subType.equalsIgnoreAsciiCase(
"vnd.sun.star.configuration-data"))
349 return new PackageImpl(
351 bRemoved, identifier);
353 else if (subType.equalsIgnoreAsciiCase(
"vnd.sun.star.configuration-schema")) {
354 return new PackageImpl(
356 bRemoved, identifier);
360 throw lang::IllegalArgumentException(
361 StrUnsupportedMediaType() + mediaType,
362 static_cast<OWeakObject *
>(
this),
363 static_cast<sal_Int16
>(-1) );
367void BackendImpl::configmgrini_verify_init(
368 Reference<XCommandEnvironment>
const & xCmdEnv )
372 const ::osl::MutexGuard guard( m_aMutex );
380 makeURL( getCachePath(),
"configmgr.ini" ),
384 if (
readLine( &line, u
"SCHEMA=", ucb_content,
385 RTL_TEXTENCODING_UTF8 ))
387 sal_Int32
index = RTL_CONSTASCII_LENGTH(
"SCHEMA=");
390 if (!token.isEmpty()) {
400 if (
readLine( &line, u
"DATA=", ucb_content,
401 RTL_TEXTENCODING_UTF8 )) {
402 sal_Int32
index = RTL_CONSTASCII_LENGTH(
"DATA=");
407 if (token[ 0 ] ==
'?')
408 token = token.substr( 1 );
424void BackendImpl::configmgrini_flush(
425 Reference<XCommandEnvironment>
const & xCmdEnv )
437 buf.append(
"SCHEMA=" );
438 while (iPos != iEnd) {
453 buf.append(
"DATA=" );
454 while (iPos != iEnd) {
467 const Reference<io::XInputStream> xData(
468 ::xmlscript::createInputStream(
469 reinterpret_cast<sal_Int8 const *
>(buf.getStr()),
479void BackendImpl::addToConfigmgrIni(
bool isSchema,
bool isURL, OUString
const & url_,
480 Reference<XCommandEnvironment>
const & xCmdEnv )
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 );
490 configmgrini_flush( xCmdEnv );
494#if HAVE_FEATURE_EXTENSIONS
495bool BackendImpl::removeFromConfigmgrIni(
496 bool isSchema, OUString
const & url_,
497 Reference<XCommandEnvironment>
const & xCmdEnv )
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)
510 ::std::optional<ConfigurationBackendDb::Data> data = readDataFromDb(url_);
512 i = std::find(
rSet.begin(),
rSet.end(), data->iniEntry);
514 if (i ==
rSet.end()) {
520 configmgrini_flush( xCmdEnv );
528BackendImpl * BackendImpl::PackageImpl::getMyBackend()
const
530 BackendImpl * pBackend =
static_cast<BackendImpl *
>(m_myBackend.get());
531 if (
nullptr == pBackend)
537 "Failed to get the BackendImpl",
538 static_cast<OWeakObject*
>(
const_cast<PackageImpl *
>(
this)));
543beans::Optional< beans::Ambiguous<sal_Bool> >
544BackendImpl::PackageImpl::isRegistered_(
545 ::osl::ResettableMutexGuard &,
547 Reference<XCommandEnvironment>
const & )
549 BackendImpl * that = getMyBackend();
552 if (that->hasActiveEntry(getURL()))
555#if HAVE_FEATURE_EXTENSIONS
556 const OUString url(getURL());
557 if (!bReg && that->m_registeredPackages)
560 bReg = that->m_registeredPackages->has(
564 return beans::Optional< beans::Ambiguous<sal_Bool> >(
565 true, beans::Ambiguous<sal_Bool>( bReg,
false ) );
569OUString encodeForXml( std::u16string_view text )
572 size_t len =
text.size();
574 for (
size_t pos = 0;
pos < len; ++
pos )
579 buf.append(
"<" );
582 buf.append(
">" );
585 buf.append(
"&" );
588 buf.append(
"'" );
591 buf.append(
""" );
598 return buf.makeStringAndClear();
602OUString replaceOrigin(
603 OUString
const & url, std::u16string_view destFolder, Reference< XCommandEnvironment >
const & xCmdEnv, Reference< XComponentContext >
const &
xContext,
bool & out_replaced)
608 std::vector<sal_Int8> filtered(
bytes.size() * 2 );
609 bool use_filtered =
false;
611 char const * pBytes =
reinterpret_cast<char const *
>(
613 std::size_t nBytes =
bytes.size();
614 size_t write_pos = 0;
617 sal_Int32
index = rtl_str_indexOfChar_WithLength( pBytes, nBytes,
'%' );
624 if ((write_pos + index) > filtered.size())
625 filtered.resize( (filtered.size() + index) * 2 );
626 memcpy( filtered.data() + write_pos, pBytes, index );
636 char const * pAdd =
"%";
638 if (nBytes > 1 && pBytes[ 0 ] ==
'%')
645 else if (rtl_str_shortenedCompare_WithLength(
648 RTL_CONSTASCII_LENGTH(
"origin%"),
649 RTL_CONSTASCII_LENGTH(
"origin%")) == 0)
651 if (origin.isEmpty()) {
654 encodeForXml( url.subView( 0, url.lastIndexOf(
'/' ) ) ),
656 RTL_TEXTENCODING_UTF8 );
658 pAdd = origin.getStr();
659 nAdd = origin.getLength();
660 pBytes += RTL_CONSTASCII_LENGTH(
"origin%");
661 nBytes -= RTL_CONSTASCII_LENGTH(
"origin%");
664 if ((write_pos + nAdd) > filtered.size())
665 filtered.resize( (filtered.size() + nAdd) * 2 );
666 memcpy( filtered.data() + write_pos, pAdd, nAdd );
671 if (write_pos < filtered.size())
672 filtered.resize( write_pos );
673 OUString newUrl(url);
674 if (!destFolder.empty())
677 sal_Int32
i = url.lastIndexOf(
'/');
678 newUrl = OUString::Concat(destFolder) + url.subView(i);
688void BackendImpl::PackageImpl::processPackage_(
689 ::osl::ResettableMutexGuard &,
690 bool doRegisterPackage,
693 Reference<XCommandEnvironment>
const & xCmdEnv )
695 BackendImpl * that = getMyBackend();
696 OUString url( getURL() );
698 if (doRegisterPackage)
700 if (getMyBackend()->activateEntry(getURL()))
702 ::std::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
704 that->addToConfigmgrIni(
m_isSchema,
false, data->iniEntry, xCmdEnv );
708 ConfigurationBackendDb::Data data;
711 const OUString sModFolder = that->createFolder(xCmdEnv);
712 bool out_replaced =
false;
713 url = replaceOrigin(url, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
715 data.dataUrl = sModFolder;
717 deleteTempFolder(sModFolder);
721 if ((that->m_eContext != Context::Bundled && !startup)
726 css::configuration::Update::get(
727 that->m_xComponentContext)->insertExtensionXcsFile(
732 css::configuration::Update::get(
733 that->m_xComponentContext)->insertExtensionXcuFile(
737 that->addToConfigmgrIni(
m_isSchema,
true, url, xCmdEnv );
739 that->addDataToDb(getURL(), data);
744#if HAVE_FEATURE_EXTENSIONS
745 if (!that->removeFromConfigmgrIni(
m_isSchema, url, xCmdEnv) &&
746 that->m_registeredPackages) {
749 that->m_registeredPackages->getEntries());
750 for (
auto const& entry : entries)
758 OStringToOUString(entry.first, RTL_TEXTENCODING_UTF8));
760 bool schema = entry.second.equalsIgnoreAsciiCase(
761 "vnd.sun.star.configuration-schema");
762 OUString url_replaced(url2);
763 ConfigurationBackendDb::Data data;
766 const OUString sModFolder = that->createFolder(xCmdEnv);
767 bool out_replaced =
false;
768 url_replaced = replaceOrigin(
769 url2, sModFolder, xCmdEnv, that->getComponentContext(), out_replaced);
771 data.dataUrl = sModFolder;
773 deleteTempFolder(sModFolder);
775 that->addToConfigmgrIni(schema,
true, url_replaced, xCmdEnv);
777 that->addDataToDb(url2, data);
779 that->m_registeredPackages->erase(entry.first);
784 makeURL( that->getCachePath(),
"registry" ),
786 "delete",
Any(
true ) );
788 catch(
const Exception&)
794 ::std::optional<ConfigurationBackendDb::Data> data = that->readDataFromDb(url);
800 css::configuration::Update::get(
801 that->m_xComponentContext)->removeExtensionXcuFile(
expandUnoRcTerm(data->iniEntry));
803 that->revokeEntryFromDb(url);
811extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
813 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any>
const& args)
815 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
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