29#include <rtl/ustring.hxx>
31#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
32#include <com/sun/star/lang/XServiceInfo.hpp>
33#include <com/sun/star/lang/XInitialization.hpp>
34#include <com/sun/star/loader/XImplementationLoader.hpp>
35#include <com/sun/star/registry/XImplementationRegistration2.hpp>
36#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
37#include <com/sun/star/reflection/XServiceTypeDescription.hpp>
38#include <com/sun/star/beans/XPropertySet.hpp>
39#include <com/sun/star/uno/RuntimeException.hpp>
40#include <com/sun/star/uno/XComponentContext.hpp>
50using namespace css::uno;
51using namespace css::loader;
52using namespace css::beans;
53using namespace css::lang;
54using namespace css::registry;
60constexpr OUStringLiteral slash_UNO_slash_REGISTRY_LINKS
61 =
u"/UNO/REGISTRY_LINKS";
62constexpr OUStringLiteral slash_IMPLEMENTATIONS
63 =
u"/IMPLEMENTATIONS";
64constexpr OUStringLiteral slash_UNO
66constexpr OUStringLiteral slash_UNO_slash_SERVICES
68constexpr OUStringLiteral slash_UNO_slash_SINGLETONS
70constexpr OUStringLiteral slash_SERVICES
72constexpr OUStringLiteral slash_UNO_slash_LOCATION
74constexpr OUStringLiteral slash_UNO_slash_ACTIVATOR
76constexpr OUStringLiteral colon_old
78constexpr OUStringLiteral com_sun_star_registry_SimpleRegistry
79 =
u"com.sun.star.registry.SimpleRegistry";
85void deleteAllLinkReferences(
const Reference < XSimpleRegistry >& xReg,
86 const Reference < XRegistryKey >& xSource)
89 Reference < XRegistryKey > xKey = xSource->openKey(
90 slash_UNO_slash_REGISTRY_LINKS );
92 if (!(xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST)))
95 const Sequence<OUString> linkNames = xKey->getAsciiListValue();
97 if (!linkNames.hasElements())
101 OUString aLinkParent;
102 Reference < XRegistryKey > xLinkParent;
107 for (
const OUString& rLinkName : linkNames)
109 aLinkName = rLinkName;
111 pTmpName = aLinkName.getStr();
113 if (pTmpName[0] != L
'/')
116 sal_Int32
nIndex = rtl_ustr_indexOfChar( pTmpName,
'%' );
118 pShortName =
nullptr;
120 pShortName = pTmpName+
nIndex;
122 while (pShortName && pShortName[1] == L
'%')
124 nIndex = rtl_ustr_indexOfChar( pShortName+2,
'%' );
126 pShortName =
nullptr;
133 aLinkName = aLinkName.copy(0, pShortName - pTmpName);
136 xReg->getRootKey()->deleteLink(aLinkName);
138 sEnd = aLinkName.lastIndexOf(
'/' );
140 aLinkParent = aLinkName.copy(0, sEnd);
142 while(!aLinkParent.isEmpty())
144 xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
146 if (xLinkParent.is() && !xLinkParent->getKeyNames().hasElements())
148 aLinkName = aLinkParent;
150 xReg->getRootKey()->deleteKey(aLinkParent);
152 sEnd = aLinkName.lastIndexOf(
'/' );
154 aLinkParent = aLinkName.copy(0, sEnd);
167void prepareLink(
const Reference < XSimpleRegistry > & xDest,
168 const Reference < XRegistryKey > & xSource,
169 const OUString& link)
172 OUString linkRefName = xSource->getKeyName();
173 OUString linkName(link);
174 bool isRelativ =
false;
178 sal_Int32
nIndex = rtl_ustr_indexOfChar( pTmpName,
'%' );
180 pShortName =
nullptr;
182 pShortName = pTmpName+
nIndex;
184 if (pTmpName[0] != L
'/')
187 while (pShortName && pShortName[1] == L
'%')
189 nIndex = rtl_ustr_indexOfChar( pShortName+2,
'%' );
191 pShortName =
nullptr;
198 linkRefName += link.subView(pShortName - pTmpName + 1);
199 linkName = link.copy(0, pShortName - pTmpName);
203 xSource->createLink(linkName, linkRefName);
205 xDest->getRootKey()->createLink(linkName, linkRefName);
211OUString searchImplForLink(
212 const Reference < XRegistryKey > & xRootKey,
213 std::u16string_view linkName,
214 std::u16string_view implName )
217 Reference < XRegistryKey > xKey = xRootKey->openKey( slash_IMPLEMENTATIONS );
220 const Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
221 OUString key_name( slash_UNO + linkName );
223 for (
const Reference < XRegistryKey >& xImplKey : subKeys)
227 if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
229 OUString oldImplName = xImplKey->getKeyName().copy(strlen(
"/IMPLEMENTATIONS/"));
230 if (implName != oldImplName)
236 catch(InvalidRegistryException&)
248OUString searchLinkTargetForImpl(
const Reference < XRegistryKey >& xRootKey,
249 std::u16string_view linkName,
250 const OUString& implName)
252 Reference < XRegistryKey > xKey = xRootKey->openKey( slash_IMPLEMENTATIONS );
256 const Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
258 OUString qualifiedLinkName( slash_UNO + linkName );
260 auto pSubKey = std::find_if(subKeys.begin(), subKeys.end(),
261 [&implName, &qualifiedLinkName](
const Reference<XRegistryKey>& rSubKey) {
262 OUString tmpImplName = rSubKey->getKeyName().copy(strlen(
"/IMPLEMENTATIONS/"));
263 return tmpImplName == implName
264 && rSubKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK;
266 if (pSubKey != subKeys.end())
267 return (*pSubKey)->getLinkTarget( qualifiedLinkName );
276void createUniqueSubEntry(
const Reference < XRegistryKey > & xSuperKey,
277 const OUString& value)
283 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
285 const Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
286 sal_Int32
length = implEntries.getLength();
292 Sequence<OUString> implEntriesNew(length);
293 auto it = implEntriesNew.getArray();
296 std::copy_if(implEntries.begin(), implEntries.end(), std::next(it),
297 [&value](
const OUString& rEntry) { return rEntry != value; });
298 xSuperKey->setAsciiListValue(implEntriesNew);
301 Sequence<OUString> implEntriesNew(length+1);
302 auto it = implEntriesNew.getArray();
305 std::copy(implEntries.begin(), implEntries.end(), std::next(it));
306 xSuperKey->setAsciiListValue(implEntriesNew);
310 Sequence<OUString> implEntriesNew {
value };
312 xSuperKey->setAsciiListValue(implEntriesNew);
319bool deleteSubEntry(
const Reference < XRegistryKey >& xSuperKey,
const OUString& value)
322 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
324 const Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
325 sal_Int32
length = implEntries.getLength();
326 sal_Int32 equals =
static_cast<sal_Int32
>(std::count(implEntries.begin(), implEntries.end(), value));
327 bool hasNoImplementations =
false;
329 if (equals == length)
331 hasNoImplementations =
true;
334 Sequence<OUString> implEntriesNew(length - equals);
336 std::copy_if(implEntries.begin(), implEntries.end(), implEntriesNew.getArray(),
337 [&value](
const OUString& rEntry) { return rEntry != value; });
338 xSuperKey->setAsciiListValue(implEntriesNew);
341 if (hasNoImplementations)
352void prepareUserLink(
const Reference < XSimpleRegistry >& xDest,
353 const OUString& linkName,
354 const OUString& linkTarget,
355 std::u16string_view implName)
357 Reference < XRegistryKey > xRootKey = xDest->getRootKey();
359 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
361 OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
363 if (!oldImplName.isEmpty())
365 createUniqueSubEntry(xDest->getRootKey()->createKey(
366 linkName + colon_old ), oldImplName);
370 if (xRootKey->isValid())
371 xRootKey->createLink(linkName, linkTarget);
377void deletePathIfPossible(
const Reference < XRegistryKey >& xRootKey,
378 const OUString& path)
382 Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
384 if (!keyNames.hasElements() &&
385 xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
387 xRootKey->deleteKey(path);
389 OUString newPath = path.copy(0, path.lastIndexOf(
'/'));
391 if (newPath.getLength() > 1)
392 deletePathIfPossible(xRootKey, newPath);
395 catch(InvalidRegistryException&)
403void deleteUserLink(
const Reference < XRegistryKey >& xRootKey,
404 const OUString& linkName,
405 std::u16string_view linkTarget,
406 const OUString& implName)
411 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
413 OUString tmpTarget = xRootKey->getLinkTarget(linkName);
415 if (tmpTarget == linkTarget)
417 xRootKey->deleteLink(linkName);
421 Reference < XRegistryKey > xOldKey = xRootKey->openKey(
422 linkName + colon_old );
425 if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
427 const Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
428 sal_Int32
length = implEntries.getLength();
429 sal_Int32 equals =
static_cast<sal_Int32
>(std::count(implEntries.begin(), implEntries.end(), implName));
430 bool hasNoImplementations =
false;
432 if (equals == length)
434 hasNoImplementations =
true;
439 if (length > equals + 1)
441 Sequence<OUString> implEntriesNew(length - equals - 1);
442 auto pNewArray = implEntriesNew.getArray();
446 for (sal_Int32 i = 0;
i <
length;
i++)
448 if (implEntries[i] != implName)
452 oldImpl = implEntries[
i];
456 pNewArray[j++] = implEntries[
i];
461 xOldKey->setAsciiListValue(implEntriesNew);
464 oldImpl = implEntries[0];
465 OUString path(xOldKey->getKeyName());
467 xRootKey->deleteKey(path);
470 OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
471 if (!oldTarget.isEmpty())
473 xRootKey->createLink(linkName, oldTarget);
477 if (hasNoImplementations)
480 OUString path(xOldKey->getKeyName());
482 xRootKey->deleteKey(path);
492 OUString path = linkName.copy(0, linkName.lastIndexOf(
'/'));
493 deletePathIfPossible(xRootKey, path);
500void prepareUserKeys(
const Reference < XSimpleRegistry >& xDest,
501 const Reference < XRegistryKey >& xUnoKey,
502 const Reference < XRegistryKey >& xKey,
503 const OUString& implName,
506 bool hasSubKeys =
false;
508 Sequence<OUString> keyNames = xKey->getKeyNames();
511 if (keyNames.hasElements())
512 relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
514 if (keyNames.getLength() == 1 &&
515 xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
519 OUString linkTarget = xKey->getLinkTarget(relativKey);
521 OUString::Concat(xKey->getKeyName().subView(xUnoKey->getKeyName().getLength()))
526 prepareUserLink(xDest, linkName, linkTarget, implName);
529 deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
533 const Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
535 if (subKeys.hasElements())
539 for (
const Reference < XRegistryKey > & rSubKey : subKeys)
541 prepareUserKeys(xDest, xUnoKey, rSubKey, implName, bRegister);
549 OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
551 Reference < XRegistryKey > xRootKey = xDest->getRootKey();
554 createUniqueSubEntry(xRootKey->createKey(keyName), implName);
558 Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
561 deleteSubEntry(rKey, implName);
562 xRootKey->deleteKey(keyName);
565 OUString path = keyName.copy(0, keyName.lastIndexOf(
'/'));
566 if( !path.isEmpty() )
568 deletePathIfPossible(xRootKey, path);
576void deleteAllImplementations(
const Reference < XSimpleRegistry >& xReg,
577 const Reference < XRegistryKey >& xSource,
578 std::u16string_view locationUrl,
579 std::vector<OUString> & implNames)
582 Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
584 if (subKeys.hasElements())
586 bool hasLocationUrl =
false;
588 for (
const Reference < XRegistryKey> & xImplKey : std::as_const(subKeys))
590 Reference < XRegistryKey > xKey = xImplKey->openKey(
591 slash_UNO_slash_LOCATION );
593 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
595 if (xKey->getAsciiValue() == locationUrl)
597 hasLocationUrl =
true;
599 OUString
implName(xImplKey->getKeyName().copy(1));
600 sal_Int32 firstDot =
implName.indexOf(
'/');
605 implNames.push_back(implName);
607 deleteAllLinkReferences(xReg, xImplKey);
609 xKey = xImplKey->openKey( slash_UNO );
612 const Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
614 for (
const Reference < XRegistryKey > & rSubKey2 : subKeys2)
616 if (rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_SERVICES ) &&
617 rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_REGISTRY_LINKS ) &&
618 rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_ACTIVATOR ) &&
619 rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_SINGLETONS ) &&
620 rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_LOCATION) )
622 prepareUserKeys(xReg, xKey, rSubKey2, implName,
false);
631 hasLocationUrl =
false;
632 OUString path(xImplKey->getKeyName());
633 xImplKey->closeKey();
634 xReg->getRootKey()->deleteKey(path);
638 subKeys = xSource->openKeys();
639 if (!subKeys.hasElements())
641 OUString path(xSource->getKeyName());
643 xReg->getRootKey()->deleteKey(path);
647 OUString path(xSource->getKeyName());
649 xReg->getRootKey()->deleteKey(path);
654void delete_all_singleton_entries(
655 Reference < registry::XRegistryKey >
const & xSingletons_section,
656 ::std::vector< OUString >
const & impl_names )
659 Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
660 Reference< registry::XRegistryKey >
const * subkeys = singletons.getConstArray();
661 for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
663 Reference< registry::XRegistryKey >
const & xSingleton = subkeys[
nPos ];
664 Reference< registry::XRegistryKey > xRegisteredImplNames(
665 xSingleton->openKey(
"REGISTERED_BY" ) );
666 if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
668 Sequence< OUString > registered_implnames;
671 registered_implnames = xRegisteredImplNames->getAsciiListValue();
673 catch (registry::InvalidValueException &)
676 auto aNonConstRange = asNonConstRange(registered_implnames);
677 sal_Int32 nOrigRegLength = registered_implnames.getLength();
678 sal_Int32 nNewLength = nOrigRegLength;
679 for ( sal_Int32 n = nOrigRegLength;
n--; )
681 OUString
const & registered_implname = registered_implnames[
n ];
683 for (
auto const& impl_name : impl_names)
685 if (impl_name == registered_implname)
687 aNonConstRange[
n ] = registered_implnames[ nNewLength -1 ];
693 if (nNewLength != nOrigRegLength)
698 xRegisteredImplNames->closeKey();
699 xSingleton->deleteKey(
"REGISTERED_BY" );
701 OUString
abs( xSingleton->getKeyName() );
702 xSingletons_section->deleteKey(
abs.copy(
abs.lastIndexOf(
'/' ) +1 ) );
706 registered_implnames.realloc( nNewLength );
707 xRegisteredImplNames->setAsciiListValue( registered_implnames );
717void deleteAllServiceEntries(
const Reference < XSimpleRegistry >& xReg,
718 const Reference < XRegistryKey >& xSource,
719 const OUString& implName)
722 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
724 if (subKeys.hasElements())
726 bool hasNoImplementations =
false;
728 for (
const Reference < XRegistryKey > & xServiceKey : std::as_const(subKeys))
730 if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
732 const Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
733 sal_Int32
length = implEntries.getLength();
734 sal_Int32 equals =
static_cast<sal_Int32
>(std::count(implEntries.begin(), implEntries.end(), implName));
736 if (equals == length)
738 hasNoImplementations =
true;
743 Sequence<OUString> implEntriesNew(length-equals);
745 std::copy_if(implEntries.begin(), implEntries.end(), implEntriesNew.getArray(),
746 [&implName](
const OUString& rEntry) { return rEntry != implName; });
748 xServiceKey->setAsciiListValue(implEntriesNew);
753 if (hasNoImplementations)
755 hasNoImplementations =
false;
756 OUString path(xServiceKey->getKeyName());
757 xServiceKey->closeKey();
758 xReg->getRootKey()->deleteKey(path);
762 subKeys = xSource->openKeys();
763 if (!subKeys.hasElements())
765 OUString path(xSource->getKeyName());
767 xReg->getRootKey()->deleteKey(path);
771 OUString path(xSource->getKeyName());
773 xReg->getRootKey()->deleteKey(path);
778bool is_supported_service(
779 OUString
const & service_name,
780 Reference< reflection::XServiceTypeDescription >
const & xService_td )
782 if (xService_td->getName() == service_name)
784 const Sequence< Reference< reflection::XServiceTypeDescription > > seq(
785 xService_td->getMandatoryServices() );
786 return std::any_of(seq.begin(), seq.end(), [&service_name](
const auto& rService) {
787 return is_supported_service( service_name, rService ); });
791void insert_singletons(
792 Reference< registry::XSimpleRegistry >
const & xDest,
793 Reference< registry::XRegistryKey >
const & xImplKey,
794 Reference< XComponentContext >
const & xContext )
798 Reference< registry::XRegistryKey > xKey( xImplKey->openKey(
"UNO/SINGLETONS" ) );
799 if (!(xKey.is() && xKey->isValid()))
802 OUString implname( xImplKey->getKeyName().copy( sizeof (
"/IMPLEMENTATIONS/") -1 ) );
804 Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
805 Reference< registry::XRegistryKey >
const *
p = xSingletons_section.getConstArray();
806 for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
808 Reference< registry::XRegistryKey >
const & xSingleton =
p[
nPos ];
809 OUString singleton_name(
810 xSingleton->getKeyName().copy(
811 implname.getLength() + sizeof (
"/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
812 OUString service_name( xSingleton->getStringValue() );
814 OUString keyname(
"/SINGLETONS/" + singleton_name );
815 Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
816 if (xKey2.is() && xKey2->isValid())
820 OUString existing_name( xKey2->getStringValue() );
821 if ( existing_name != service_name )
823 Reference< container::XHierarchicalNameAccess > xTDMgr;
825 "/singletons/com.sun.star.reflection.theTypeDescriptionManager";
826 xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
833 Reference< reflection::XServiceTypeDescription > xExistingService_td;
834 xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
835 if (! xExistingService_td.is())
837 throw RuntimeException(
"cannot get service type description: " + existing_name );
842 if (! is_supported_service( service_name, xExistingService_td ))
844 throw registry::CannotRegisterImplementationException(
845 "existing singleton service (" + singleton_name +
"=" + existing_name +
") "
846 " does not support given one: " + service_name);
849 catch (
const container::NoSuchElementException & exc)
852 throw css::lang::WrappedTargetRuntimeException(
853 "cannot get service type description: " + exc.Message,
858 catch (registry::InvalidValueException &)
861 xKey2->setStringValue( service_name );
867 xKey2 = xDest->getRootKey()->createKey( keyname );
868 xKey2->setStringValue( service_name );
871 Reference< registry::XRegistryKey > xRegisteredImplNames(
872 xKey2->openKey(
"REGISTERED_BY" ) );
873 if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
876 xRegisteredImplNames = xKey2->createKey(
"REGISTERED_BY" );
879 Sequence< OUString > implnames;
882 implnames = xRegisteredImplNames->getAsciiListValue();
884 catch (registry::InvalidValueException &)
891 implnames.realloc( implnames.getLength() +1 );
892 implnames.getArray()[ implnames.getLength() -1 ] = implname;
893 xRegisteredImplNames->setAsciiListValue( implnames );
902 const Reference < XSimpleRegistry >& xDest,
903 const Reference < XRegistryKey >& xSource,
904 const OUString& implementationLoaderUrl,
905 const OUString& locationUrl,
906 Reference< XComponentContext >
const & xContext )
909 const Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
911 if (!subKeys.hasElements())
913 throw InvalidRegistryException(
914 "prepareRegistry(): source registry is empty" );
917 for (
const Reference < XRegistryKey >& xImplKey : subKeys)
919 Reference < XRegistryKey > xKey = xImplKey->openKey(
920 slash_UNO_slash_SERVICES );
925 const Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
927 OUString
implName = xImplKey->getKeyName().copy(1);
928 sal_Int32 firstDot =
implName.indexOf(
'/');
933 sal_Int32 offset = xKey->getKeyName().getLength() + 1;
935 for (
const Reference < XRegistryKey >& rServiceKey : serviceKeys)
937 OUString serviceName = rServiceKey->getKeyName().copy(offset);
939 createUniqueSubEntry(
940 xDest->getRootKey()->createKey(
941 slash_SERVICES + serviceName ),
945 xKey = xImplKey->openKey( slash_UNO );
948 const Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
950 for (
const Reference < XRegistryKey >& rSubKey2 : subKeys2)
952 if (rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_SERVICES) &&
953 rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_REGISTRY_LINKS ) &&
954 rSubKey2->getKeyName() != Concat2View(xImplKey->getKeyName() + slash_UNO_slash_SINGLETONS ))
956 prepareUserKeys(xDest, xKey, rSubKey2, implName,
true);
963 xKey = xImplKey->createKey( slash_UNO_slash_LOCATION );
967 xKey->setAsciiValue(locationUrl);
971 xKey = xImplKey->createKey( slash_UNO_slash_ACTIVATOR );
975 xKey->setAsciiValue(implementationLoaderUrl);
978 xKey = xImplKey->openKey( slash_UNO_slash_SERVICES );
980 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
983 const Sequence<OUString> linkNames = xKey->getAsciiListValue();
985 for (
const OUString& rLinkName : linkNames)
987 prepareLink(xDest, xImplKey, rLinkName);
991 insert_singletons( xDest, xImplKey, xContext );
996void findImplementations(
const Reference < XRegistryKey > & xSource,
997 std::vector<OUString>& implNames)
999 bool isImplKey =
false;
1003 Reference < XRegistryKey > xKey = xSource->openKey(
1004 slash_UNO_slash_SERVICES );
1006 if (xKey.is() && xKey->getKeyNames().hasElements())
1010 OUString
implName = xSource->getKeyName().copy(1).replace(
'/',
'.');
1011 sal_Int32 firstDot =
implName.indexOf(
'.');
1016 implNames.push_back(implName);
1019 catch(InvalidRegistryException&)
1023 if (isImplKey)
return;
1027 const Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1029 for (
const Reference < XRegistryKey >& rSubKey : subKeys)
1031 findImplementations(rSubKey, implNames);
1034 catch(InvalidRegistryException&)
1040class ImplementationRegistration
1041 :
public WeakImplHelper< XImplementationRegistration2, XServiceInfo, XInitialization >
1044 explicit ImplementationRegistration(
const Reference < XComponentContext > & rSMgr );
1052 virtual void SAL_CALL registerImplementation(
1053 const OUString& implementationLoader,
1054 const OUString& location,
1055 const Reference < XSimpleRegistry > & xReg)
override;
1057 virtual sal_Bool SAL_CALL revokeImplementation(
1058 const OUString& location,
1059 const Reference < XSimpleRegistry >& xReg)
override;
1061 virtual Sequence< OUString > SAL_CALL getImplementations(
1062 const OUString& implementationLoader,
1063 const OUString& location)
override;
1064 virtual Sequence< OUString > SAL_CALL checkInstantiation(
1065 const OUString& implementationName)
override;
1068 virtual void SAL_CALL registerImplementationWithLocation(
1069 const OUString& implementationLoader,
1070 const OUString& location,
1071 const OUString& registeredLocation,
1072 const Reference < XSimpleRegistry > & xReg)
override;
1075 virtual void SAL_CALL initialize(
1076 const css::uno::Sequence< css::uno::Any >& aArguments )
override;
1079 void prepareRegister(
1080 const OUString& implementationLoader,
1081 const OUString& location,
1082 const OUString& registeredLocation,
1083 const Reference < XSimpleRegistry > & xReg);
1086 static void doRegister(
const Reference < XMultiComponentFactory >& xSMgr,
1087 const Reference < XComponentContext > &xCtx,
1088 const Reference < XImplementationLoader >& xAct,
1089 const Reference < XSimpleRegistry >& xDest,
1090 const OUString& implementationLoaderUrl,
1091 const OUString& locationUrl,
1092 const OUString& registeredLocationUrl);
1097 static void doRevoke(
const Reference < XSimpleRegistry >& xDest,
1098 std::u16string_view locationUrl );
1100 Reference< XSimpleRegistry > getRegistryFromServiceManager()
const;
1102 static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
1103 const Reference< XMultiComponentFactory > &rSMgr,
1104 const Reference < XComponentContext > & rCtx );
1107 Reference < XMultiComponentFactory >
m_xSMgr;
1108 Reference < XComponentContext >
m_xCtx;
1114ImplementationRegistration::ImplementationRegistration(
const Reference < XComponentContext > & xCtx )
1115 :
m_xSMgr( xCtx->getServiceManager() )
1120OUString ImplementationRegistration::getImplementationName()
1122 return "com.sun.star.comp.stoc.ImplementationRegistration";
1126sal_Bool ImplementationRegistration::supportsService(
const OUString& ServiceName)
1132Sequence< OUString > ImplementationRegistration::getSupportedServiceNames()
1134 return {
"com.sun.star.registry.ImplementationRegistration" };
1137Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
const
1139 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1140 Reference < XSimpleRegistry > xRegistry;
1142 if( xPropSet.is() ) {
1146 Any aAny = xPropSet->getPropertyValue(
Registry );
1148 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1152 catch( UnknownPropertyException & ) {
1163void ImplementationRegistration::initialize(
1164 const css::uno::Sequence< css::uno::Any >& aArgs )
1167 if( aArgs.getLength() != 4 ) {
1168 throw IllegalArgumentException(
1169 "ImplementationRegistration::initialize() expects 4 parameters, got " + OUString::number( aArgs.getLength() ),
1170 Reference<XInterface > (), 0 );
1173 Reference< XImplementationLoader > rLoader;
1174 OUString loaderServiceName;
1175 OUString locationUrl;
1176 Reference< XSimpleRegistry > rReg;
1179 if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1180 aArgs.getConstArray()[0] >>= rLoader;
1182 if( !rLoader.is()) {
1183 throw IllegalArgumentException(
1184 "ImplementationRegistration::initialize() invalid first parameter,"
1186 ", got " + aArgs.getConstArray()[0].getValueTypeName(),
1187 Reference< XInterface > (), 0 );
1191 if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
1192 aArgs.getConstArray()[1] >>= loaderServiceName;
1194 if( loaderServiceName.isEmpty() ) {
1195 throw IllegalArgumentException(
1196 "ImplementationRegistration::initialize() invalid second parameter,"
1197 "expected string, got " + aArgs.getConstArray()[1].getValueTypeName(),
1198 Reference< XInterface > (), 0 );
1202 if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
1203 aArgs.getConstArray()[2] >>= locationUrl;
1205 if( locationUrl.isEmpty() ) {
1206 throw IllegalArgumentException(
1207 "ImplementationRegistration::initialize() invalid third parameter,"
1208 "expected string, got " + aArgs.getConstArray()[2].getValueTypeName(),
1209 Reference< XInterface > (), 0 );
1213 if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1214 aArgs.getConstArray()[3] >>= rReg;
1218 rReg = getRegistryFromServiceManager();
1220 throw IllegalArgumentException(
1221 "ImplementationRegistration::initialize() invalid fourth parameter,"
1223 ", got " + aArgs.getConstArray()[3].getValueTypeName(),
1224 Reference< XInterface > (), 0 );
1228 doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
1234void ImplementationRegistration::registerImplementationWithLocation(
1235 const OUString& implementationLoaderUrl,
1236 const OUString& locationUrl,
1237 const OUString& registeredLocationUrl,
1238 const Reference < XSimpleRegistry > & xReg)
1241 implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
1245void ImplementationRegistration::prepareRegister(
1246 const OUString& implementationLoaderUrl,
1247 const OUString& locationUrl,
1248 const OUString& registeredLocationUrl,
1249 const Reference < XSimpleRegistry > & xReg)
1252 OUString activatorName;
1254 if (!implementationLoaderUrl.isEmpty())
1256 activatorName = implementationLoaderUrl.getToken(0,
':');
1264 throw CannotRegisterImplementationException(
1265 "ImplementationRegistration::registerImplementation() "
1266 "no componentcontext available to instantiate loader" );
1271 Reference < XImplementationLoader > xAct(
1272 m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1275 throw CannotRegisterImplementationException(
1276 "ImplementationRegistration::registerImplementation() - The service "
1277 + activatorName +
" cannot be instantiated" );
1280 Reference < XSimpleRegistry > xRegistry;
1289 xRegistry = getRegistryFromServiceManager();
1292 if ( xRegistry.is())
1294 doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implementationLoaderUrl,
1295 locationUrl, registeredLocationUrl);
1299 catch( CannotRegisterImplementationException & )
1303 catch(
const InvalidRegistryException & e )
1305 throw CannotRegisterImplementationException(
1306 "ImplementationRegistration::registerImplementation() "
1307 "InvalidRegistryException during registration (" + e.Message +
")" );
1309 catch(
const MergeConflictException & e )
1311 throw CannotRegisterImplementationException(
1312 "ImplementationRegistration::registerImplementation() "
1313 "MergeConflictException during registration (" + e.Message +
")" );
1321void ImplementationRegistration::registerImplementation(
1322 const OUString& implementationLoaderUrl,
1323 const OUString& locationUrl,
1324 const Reference < XSimpleRegistry > & xReg)
1326 prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1332sal_Bool ImplementationRegistration::revokeImplementation(
const OUString& location,
1333 const Reference < XSimpleRegistry >& xReg)
1337 Reference < XSimpleRegistry > xRegistry;
1343 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1344 if( xPropSet.is() ) {
1346 Any aAny = xPropSet->getPropertyValue(
Registry );
1348 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
1353 catch ( UnknownPropertyException & ) {
1362 doRevoke(xRegistry, location);
1365 catch( InvalidRegistryException & )
1369 OSL_FAIL(
"InvalidRegistryException during revokeImplementation" );
1379Sequence< OUString > ImplementationRegistration::getImplementations(
1380 const OUString & implementationLoaderUrl,
1381 const OUString & locationUrl)
1383 OUString activatorName;
1385 if (!implementationLoaderUrl.isEmpty())
1387 activatorName = implementationLoaderUrl.getToken(0,
':');
1396 Reference < XImplementationLoader > xAct(
1397 m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1402 Reference < XSimpleRegistry > xReg =
1403 createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1409 xReg->open(OUString() ,
false,
true);
1410 Reference < XRegistryKey > xImpl;
1413 xImpl = xReg->getRootKey()->createKey( slash_IMPLEMENTATIONS );
1415 if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1417 std::vector<OUString> implNames;
1419 findImplementations(xImpl, implNames);
1421 if (!implNames.empty())
1431 catch(MergeConflictException&)
1434 catch(InvalidRegistryException&)
1441 return Sequence<OUString>();
1447Sequence< OUString > ImplementationRegistration::checkInstantiation(
const OUString&)
1449 OSL_FAIL(
"ImplementationRegistration::checkInstantiation not implemented" );
1450 return Sequence<OUString>();
1457void ImplementationRegistration::doRevoke(
1458 const Reference < XSimpleRegistry >& xDest,
1459 std::u16string_view locationUrl)
1465 std::vector<OUString> aNames;
1467 Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1469 Reference < XRegistryKey > xKey =
1470 xRootKey->openKey( slash_IMPLEMENTATIONS );
1471 if (xKey.is() && xKey->isValid())
1473 deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1476 xKey = xRootKey->openKey( slash_SERVICES );
1479 for (
auto const& name : aNames)
1481 deleteAllServiceEntries(xDest, xKey, name);
1485 xKey = xRootKey->openKey(
"/SINGLETONS" );
1486 if (xKey.is() && xKey->isValid())
1488 delete_all_singleton_entries( xKey, aNames );
1492 xRootKey->closeKey();
1493 if (xKey.is() && xKey->isValid() )
1497void ImplementationRegistration::doRegister(
1498 const Reference< XMultiComponentFactory > & xSMgr,
1499 const Reference< XComponentContext > &xCtx,
1500 const Reference < XImplementationLoader > & xAct,
1501 const Reference < XSimpleRegistry >& xDest,
1502 const OUString& implementationLoaderUrl,
1503 const OUString& locationUrl,
1504 const OUString& registeredLocationUrl)
1509 Reference < XSimpleRegistry > xReg =
1510 createTemporarySimpleRegistry( xSMgr, xCtx );
1511 Reference < XRegistryKey > xSourceKey;
1513 if (!(xAct.is() && xReg.is() && xDest.is()))
1518 xReg->open(OUString() ,
false,
true);
1521 xSourceKey = xReg->getRootKey()->createKey( slash_IMPLEMENTATIONS );
1525 xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1528 throw CannotRegisterImplementationException(
1529 "ImplementationRegistration::doRegistration() component registration signaled failure" );
1532 prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1534 xSourceKey->closeKey();
1536 xSourceKey = xReg->getRootKey();
1537 Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1539 xDestKey->closeKey();
1540 xSourceKey->closeKey();
1544 if ( xSourceKey->isValid() )
1545 xSourceKey->closeKey();
1547 catch(CannotRegisterImplementationException&)
1549 if ( xSourceKey->isValid() )
1550 xSourceKey->closeKey();
1557Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1558 const Reference< XMultiComponentFactory > &rSMgr,
1559 const Reference < XComponentContext > & xCtx)
1562 Reference < XSimpleRegistry > xReg(
1563 rSMgr->createInstanceWithContext(
1564 com_sun_star_registry_SimpleRegistry, xCtx ),
1566 OSL_ASSERT( xReg.is() );
1572extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1574 css::uno::XComponentContext *context,
1575 css::uno::Sequence<css::uno::Any>
const &)
1577 return cppu::acquire(
new ImplementationRegistration(context));
Reference< XComponentContext > m_xCtx
Reference< lang::XMultiComponentFactory > m_xSMgr
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_stoc_ImplementationRegistration_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
rtl::OUString getTypeName(rtl::OUString const &rEnvDcp)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Any SAL_CALL getCaughtException()
constexpr OUStringLiteral first
static void mergeKeys(Reference< registry::XRegistryKey > const &xDest, Reference< registry::XRegistryKey > const &xSource, t_links &links)
SwNodeOffset abs(const SwNodeOffset &a)