LibreOffice Module stoc (master) 1
implreg.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#include <string.h>
21#include <string_view>
22#include <vector>
23
25#include <cppuhelper/weak.hxx>
29#include <rtl/ustring.hxx>
30
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>
41
42#include "mergekeys.hxx"
43
44#if defined(_WIN32)
45#include <io.h>
46#endif
47
48
49using namespace com::sun::star;
50using namespace css::uno;
51using namespace css::loader;
52using namespace css::beans;
53using namespace css::lang;
54using namespace css::registry;
55using namespace cppu;
56using namespace osl;
57
58namespace {
59
60constexpr OUStringLiteral slash_UNO_slash_REGISTRY_LINKS
61 = u"/UNO/REGISTRY_LINKS";
62constexpr OUStringLiteral slash_IMPLEMENTATIONS
63 = u"/IMPLEMENTATIONS";
64constexpr OUStringLiteral slash_UNO
65 = u"/UNO";
66constexpr OUStringLiteral slash_UNO_slash_SERVICES
67 = u"/UNO/SERVICES";
68constexpr OUStringLiteral slash_UNO_slash_SINGLETONS
69 = u"/UNO/SINGLETONS";
70constexpr OUStringLiteral slash_SERVICES
71 = u"/SERVICES/";
72constexpr OUStringLiteral slash_UNO_slash_LOCATION
73 = u"/UNO/LOCATION";
74constexpr OUStringLiteral slash_UNO_slash_ACTIVATOR
75 = u"/UNO/ACTIVATOR";
76constexpr OUStringLiteral colon_old
77 = u":old";
78constexpr OUStringLiteral com_sun_star_registry_SimpleRegistry
79 = u"com.sun.star.registry.SimpleRegistry";
80constexpr OUStringLiteral Registry
81 = u"Registry";
82
83// static deleteAllLinkReferences()
84
85void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
86 const Reference < XRegistryKey >& xSource)
87 // throw ( InvalidRegistryException, RuntimeException )
88{
89 Reference < XRegistryKey > xKey = xSource->openKey(
90 slash_UNO_slash_REGISTRY_LINKS );
91
92 if (!(xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST)))
93 return;
94
95 const Sequence<OUString> linkNames = xKey->getAsciiListValue();
96
97 if (!linkNames.hasElements())
98 return;
99
100 OUString aLinkName;
101 OUString aLinkParent;
102 Reference < XRegistryKey > xLinkParent;
103 const sal_Unicode* pTmpName = nullptr;
104 const sal_Unicode* pShortName = nullptr;
105 sal_Int32 sEnd = 0;
106
107 for (const OUString& rLinkName : linkNames)
108 {
109 aLinkName = rLinkName;
110
111 pTmpName = aLinkName.getStr();
112
113 if (pTmpName[0] != L'/')
114 continue;
115
116 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
117 if ( nIndex == -1 )
118 pShortName = nullptr;
119 else
120 pShortName = pTmpName+nIndex;
121
122 while (pShortName && pShortName[1] == L'%')
123 {
124 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
125 if ( nIndex == -1 )
126 pShortName = nullptr;
127 else
128 pShortName += nIndex+2;
129 }
130
131 if (pShortName)
132 {
133 aLinkName = aLinkName.copy(0, pShortName - pTmpName);
134 }
135
136 xReg->getRootKey()->deleteLink(aLinkName);
137
138 sEnd = aLinkName.lastIndexOf( '/' );
139
140 aLinkParent = aLinkName.copy(0, sEnd);
141
142 while(!aLinkParent.isEmpty())
143 {
144 xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
145
146 if (xLinkParent.is() && !xLinkParent->getKeyNames().hasElements())
147 {
148 aLinkName = aLinkParent;
149
150 xReg->getRootKey()->deleteKey(aLinkParent);
151
152 sEnd = aLinkName.lastIndexOf( '/' );
153
154 aLinkParent = aLinkName.copy(0, sEnd);
155 }
156 else
157 {
158 break;
159 }
160 }
161 }
162}
163
164
165// static prepareLink
166
167void prepareLink( const Reference < XSimpleRegistry > & xDest,
168 const Reference < XRegistryKey > & xSource,
169 const OUString& link)
170 // throw ( InvalidRegistryException, RuntimeException )
171{
172 OUString linkRefName = xSource->getKeyName();
173 OUString linkName(link);
174 bool isRelativ = false;
175
176 const sal_Unicode* pTmpName = link.getStr();
177 const sal_Unicode* pShortName;
178 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
179 if ( nIndex == -1 )
180 pShortName = nullptr;
181 else
182 pShortName = pTmpName+nIndex;
183
184 if (pTmpName[0] != L'/')
185 isRelativ = true;
186
187 while (pShortName && pShortName[1] == L'%')
188 {
189 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
190 if ( nIndex == -1 )
191 pShortName = nullptr;
192 else
193 pShortName += nIndex+2;
194 }
195
196 if (pShortName)
197 {
198 linkRefName += link.subView(pShortName - pTmpName + 1);
199 linkName = link.copy(0, pShortName - pTmpName);
200 }
201
202 if (isRelativ)
203 xSource->createLink(linkName, linkRefName);
204 else
205 xDest->getRootKey()->createLink(linkName, linkRefName);
206}
207
208
209// static searchImplForLink
210
211OUString searchImplForLink(
212 const Reference < XRegistryKey > & xRootKey,
213 std::u16string_view linkName,
214 std::u16string_view implName )
215 // throw ( InvalidRegistryException, RuntimeException )
216{
217 Reference < XRegistryKey > xKey = xRootKey->openKey( slash_IMPLEMENTATIONS );
218 if (xKey.is())
219 {
220 const Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
221 OUString key_name( slash_UNO + linkName );
222
223 for (const Reference < XRegistryKey >& xImplKey : subKeys)
224 {
225 try
226 {
227 if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
228 {
229 OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
230 if (implName != oldImplName)
231 {
232 return oldImplName;
233 }
234 }
235 }
236 catch(InvalidRegistryException&)
237 {
238 }
239 }
240 }
241
242 return OUString();
243}
244
245
246// static searchLinkTargetForImpl
247
248OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
249 std::u16string_view linkName,
250 const OUString& implName)
251{
252 Reference < XRegistryKey > xKey = xRootKey->openKey( slash_IMPLEMENTATIONS );
253
254 if (xKey.is())
255 {
256 const Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
257
258 OUString qualifiedLinkName( slash_UNO + linkName );
259
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;
265 });
266 if (pSubKey != subKeys.end())
267 return (*pSubKey)->getLinkTarget( qualifiedLinkName );
268 }
269
270 return OUString();
271}
272
273
274// static createUniqueSubEntry
275
276void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
277 const OUString& value)
278 // throw ( InvalidRegistryException, RuntimeException )
279{
280 if (!xSuperKey.is())
281 return;
282
283 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
284 {
285 const Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
286 sal_Int32 length = implEntries.getLength();
287
288 bool bReady = comphelper::findValue(implEntries, value) != -1;
289
290 if (bReady)
291 {
292 Sequence<OUString> implEntriesNew(length);
293 auto it = implEntriesNew.getArray();
294 *it = value;
295
296 std::copy_if(implEntries.begin(), implEntries.end(), std::next(it),
297 [&value](const OUString& rEntry) { return rEntry != value; });
298 xSuperKey->setAsciiListValue(implEntriesNew);
299 } else
300 {
301 Sequence<OUString> implEntriesNew(length+1);
302 auto it = implEntriesNew.getArray();
303 *it = value;
304
305 std::copy(implEntries.begin(), implEntries.end(), std::next(it));
306 xSuperKey->setAsciiListValue(implEntriesNew);
307 }
308 } else
309 {
310 Sequence<OUString> implEntriesNew { value };
311
312 xSuperKey->setAsciiListValue(implEntriesNew);
313 }
314}
315
316
317// static deleteSubEntry
318
319bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value)
320 // throw ( InvalidRegistryException, RuntimeException )
321{
322 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
323 {
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;
328
329 if (equals == length)
330 {
331 hasNoImplementations = true;
332 } else
333 {
334 Sequence<OUString> implEntriesNew(length - equals);
335
336 std::copy_if(implEntries.begin(), implEntries.end(), implEntriesNew.getArray(),
337 [&value](const OUString& rEntry) { return rEntry != value; });
338 xSuperKey->setAsciiListValue(implEntriesNew);
339 }
340
341 if (hasNoImplementations)
342 {
343 return true;
344 }
345 }
346 return false;
347}
348
349
350// static prepareUserLink
351
352void prepareUserLink(const Reference < XSimpleRegistry >& xDest,
353 const OUString& linkName,
354 const OUString& linkTarget,
355 std::u16string_view implName)
356{
357 Reference < XRegistryKey > xRootKey = xDest->getRootKey();
358
359 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
360 {
361 OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
362
363 if (!oldImplName.isEmpty())
364 {
365 createUniqueSubEntry(xDest->getRootKey()->createKey(
366 linkName + colon_old ), oldImplName);
367 }
368 }
369
370 if (xRootKey->isValid())
371 xRootKey->createLink(linkName, linkTarget);
372}
373
374
375// static deleteUserLink
376
377void deletePathIfPossible(const Reference < XRegistryKey >& xRootKey,
378 const OUString& path)
379{
380 try
381 {
382 Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
383
384 if (!keyNames.hasElements() &&
385 xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
386 {
387 xRootKey->deleteKey(path);
388
389 OUString newPath = path.copy(0, path.lastIndexOf('/'));
390
391 if (newPath.getLength() > 1)
392 deletePathIfPossible(xRootKey, newPath);
393 }
394 }
395 catch(InvalidRegistryException&)
396 {
397 }
398}
399
400
401// static deleteUserLink
402
403void deleteUserLink(const Reference < XRegistryKey >& xRootKey,
404 const OUString& linkName,
405 std::u16string_view linkTarget,
406 const OUString& implName)
407 // throw ( InvalidRegistryException, RuntimeException )
408{
409 bool bClean = false;
410
411 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
412 {
413 OUString tmpTarget = xRootKey->getLinkTarget(linkName);
414
415 if (tmpTarget == linkTarget)
416 {
417 xRootKey->deleteLink(linkName);
418 }
419 }
420
421 Reference < XRegistryKey > xOldKey = xRootKey->openKey(
422 linkName + colon_old );
423 if (xOldKey.is())
424 {
425 if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
426 {
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;
431
432 if (equals == length)
433 {
434 hasNoImplementations = true;
435 } else
436 {
437 OUString oldImpl;
438
439 if (length > equals + 1)
440 {
441 Sequence<OUString> implEntriesNew(length - equals - 1);
442 auto pNewArray = implEntriesNew.getArray();
443
444 sal_Int32 j = 0;
445 bool first = true;
446 for (sal_Int32 i = 0; i < length; i++)
447 {
448 if (implEntries[i] != implName)
449 {
450 if (first)
451 {
452 oldImpl = implEntries[i];
453 first = false;
454 } else
455 {
456 pNewArray[j++] = implEntries[i];
457 }
458 }
459 }
460
461 xOldKey->setAsciiListValue(implEntriesNew);
462 } else
463 {
464 oldImpl = implEntries[0];
465 OUString path(xOldKey->getKeyName());
466 xOldKey->closeKey();
467 xRootKey->deleteKey(path);
468 }
469
470 OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
471 if (!oldTarget.isEmpty())
472 {
473 xRootKey->createLink(linkName, oldTarget);
474 }
475 }
476
477 if (hasNoImplementations)
478 {
479 bClean = true;
480 OUString path(xOldKey->getKeyName());
481 xOldKey->closeKey();
482 xRootKey->deleteKey(path);
483 }
484 }
485 } else
486 {
487 bClean = true;
488 }
489
490 if (bClean)
491 {
492 OUString path = linkName.copy(0, linkName.lastIndexOf('/'));
493 deletePathIfPossible(xRootKey, path);
494 }
495}
496
497
498// static prepareUserKeys
499
500void prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
501 const Reference < XRegistryKey >& xUnoKey,
502 const Reference < XRegistryKey >& xKey,
503 const OUString& implName,
504 bool bRegister)
505{
506 bool hasSubKeys = false;
507
508 Sequence<OUString> keyNames = xKey->getKeyNames();
509
510 OUString relativKey;
511 if (keyNames.hasElements())
512 relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
513
514 if (keyNames.getLength() == 1 &&
515 xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
516 {
517 hasSubKeys = true;
518
519 OUString linkTarget = xKey->getLinkTarget(relativKey);
520 OUString linkName(
521 OUString::Concat(xKey->getKeyName().subView(xUnoKey->getKeyName().getLength()))
522 + "/" + relativKey);
523
524 if (bRegister)
525 {
526 prepareUserLink(xDest, linkName, linkTarget, implName);
527 } else
528 {
529 deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
530 }
531 } else
532 {
533 const Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
534
535 if (subKeys.hasElements())
536 {
537 hasSubKeys = true;
538
539 for (const Reference < XRegistryKey > & rSubKey : subKeys)
540 {
541 prepareUserKeys(xDest, xUnoKey, rSubKey, implName, bRegister);
542 }
543 }
544 }
545
546 if (hasSubKeys)
547 return;
548
549 OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
550
551 Reference < XRegistryKey > xRootKey = xDest->getRootKey();
552 if (bRegister)
553 {
554 createUniqueSubEntry(xRootKey->createKey(keyName), implName);
555 }
556 else
557 {
558 Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
559 if( rKey.is() )
560 {
561 deleteSubEntry(rKey, implName);
562 xRootKey->deleteKey(keyName);
563 }
564
565 OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
566 if( !path.isEmpty() )
567 {
568 deletePathIfPossible(xRootKey, path);
569 }
570 }
571}
572
573
574// static deleteAllImplementations
575
576void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg,
577 const Reference < XRegistryKey >& xSource,
578 std::u16string_view locationUrl,
579 std::vector<OUString> & implNames)
580 // throw (InvalidRegistryException, RuntimeException)
581{
582 Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
583
584 if (subKeys.hasElements())
585 {
586 bool hasLocationUrl = false;
587
588 for (const Reference < XRegistryKey> & xImplKey : std::as_const(subKeys))
589 {
590 Reference < XRegistryKey > xKey = xImplKey->openKey(
591 slash_UNO_slash_LOCATION );
592
593 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
594 {
595 if (xKey->getAsciiValue() == locationUrl)
596 {
597 hasLocationUrl = true;
598
599 OUString implName(xImplKey->getKeyName().copy(1));
600 sal_Int32 firstDot = implName.indexOf('/');
601
602 if (firstDot >= 0)
603 implName = implName.copy(firstDot + 1);
604
605 implNames.push_back(implName);
606
607 deleteAllLinkReferences(xReg, xImplKey);
608
609 xKey = xImplKey->openKey( slash_UNO );
610 if (xKey.is())
611 {
612 const Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
613
614 for (const Reference < XRegistryKey > & rSubKey2 : subKeys2)
615 {
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) )
621 {
622 prepareUserKeys(xReg, xKey, rSubKey2, implName, false);
623 }
624 }
625 }
626 }
627 }
628
629 if (hasLocationUrl)
630 {
631 hasLocationUrl = false;
632 OUString path(xImplKey->getKeyName());
633 xImplKey->closeKey();
634 xReg->getRootKey()->deleteKey(path);
635 }
636 }
637
638 subKeys = xSource->openKeys();
639 if (!subKeys.hasElements())
640 {
641 OUString path(xSource->getKeyName());
642 xSource->closeKey();
643 xReg->getRootKey()->deleteKey(path);
644 }
645 } else
646 {
647 OUString path(xSource->getKeyName());
648 xSource->closeKey();
649 xReg->getRootKey()->deleteKey(path);
650 }
651}
652
653
654void delete_all_singleton_entries(
655 Reference < registry::XRegistryKey > const & xSingletons_section,
656 ::std::vector< OUString > const & impl_names )
657 // throw (InvalidRegistryException, RuntimeException)
658{
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--; )
662 {
663 Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
664 Reference< registry::XRegistryKey > xRegisteredImplNames(
665 xSingleton->openKey( "REGISTERED_BY" ) );
666 if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
667 {
668 Sequence< OUString > registered_implnames;
669 try
670 {
671 registered_implnames = xRegisteredImplNames->getAsciiListValue();
672 }
673 catch (registry::InvalidValueException &)
674 {
675 }
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--; )
680 {
681 OUString const & registered_implname = registered_implnames[ n ];
682
683 for (auto const& impl_name : impl_names)
684 {
685 if (impl_name == registered_implname)
686 {
687 aNonConstRange[ n ] = registered_implnames[ nNewLength -1 ];
688 --nNewLength;
689 }
690 }
691 }
692
693 if (nNewLength != nOrigRegLength)
694 {
695 if (0 == nNewLength)
696 {
697 // remove whole entry
698 xRegisteredImplNames->closeKey();
699 xSingleton->deleteKey( "REGISTERED_BY" );
700 // registry key cannot provide its relative name, only absolute :(
701 OUString abs( xSingleton->getKeyName() );
702 xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
703 }
704 else
705 {
706 registered_implnames.realloc( nNewLength );
707 xRegisteredImplNames->setAsciiListValue( registered_implnames );
708 }
709 }
710 }
711 }
712}
713
714
715// static deleteAllServiceEntries
716
717void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg,
718 const Reference < XRegistryKey >& xSource,
719 const OUString& implName)
720 // throw ( InvalidRegistryException, RuntimeException )
721{
722 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
723
724 if (subKeys.hasElements())
725 {
726 bool hasNoImplementations = false;
727
728 for (const Reference < XRegistryKey > & xServiceKey : std::as_const(subKeys))
729 {
730 if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
731 {
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));
735
736 if (equals == length)
737 {
738 hasNoImplementations = true;
739 } else
740 {
741 if (equals > 0)
742 {
743 Sequence<OUString> implEntriesNew(length-equals);
744
745 std::copy_if(implEntries.begin(), implEntries.end(), implEntriesNew.getArray(),
746 [&implName](const OUString& rEntry) { return rEntry != implName; });
747
748 xServiceKey->setAsciiListValue(implEntriesNew);
749 }
750 }
751 }
752
753 if (hasNoImplementations)
754 {
755 hasNoImplementations = false;
756 OUString path(xServiceKey->getKeyName());
757 xServiceKey->closeKey();
758 xReg->getRootKey()->deleteKey(path);
759 }
760 }
761
762 subKeys = xSource->openKeys();
763 if (!subKeys.hasElements())
764 {
765 OUString path(xSource->getKeyName());
766 xSource->closeKey();
767 xReg->getRootKey()->deleteKey(path);
768 }
769 } else
770 {
771 OUString path(xSource->getKeyName());
772 xSource->closeKey();
773 xReg->getRootKey()->deleteKey(path);
774 }
775}
776
777
778bool is_supported_service(
779 OUString const & service_name,
780 Reference< reflection::XServiceTypeDescription > const & xService_td )
781{
782 if (xService_td->getName() == service_name)
783 return true;
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 ); });
788}
789
790
791void insert_singletons(
792 Reference< registry::XSimpleRegistry > const & xDest,
793 Reference< registry::XRegistryKey > const & xImplKey,
794 Reference< XComponentContext > const & xContext )
795 // throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
796{
797 // singletons
798 Reference< registry::XRegistryKey > xKey( xImplKey->openKey( "UNO/SINGLETONS" ) );
799 if (!(xKey.is() && xKey->isValid()))
800 return;
801
802 OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
803 // singleton entries
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--; )
807 {
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() );
813
814 OUString keyname( "/SINGLETONS/" + singleton_name );
815 Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
816 if (xKey2.is() && xKey2->isValid())
817 {
818 try
819 {
820 OUString existing_name( xKey2->getStringValue() );
821 if ( existing_name != service_name )
822 {
823 Reference< container::XHierarchicalNameAccess > xTDMgr;
824 OUString the_tdmgr =
825 "/singletons/com.sun.star.reflection.theTypeDescriptionManager";
826 xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
827 if (! xTDMgr.is())
828 {
829 throw RuntimeException( "cannot get singleton " + the_tdmgr );
830 }
831 try
832 {
833 Reference< reflection::XServiceTypeDescription > xExistingService_td;
834 xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
835 if (! xExistingService_td.is())
836 {
837 throw RuntimeException( "cannot get service type description: " + existing_name );
838 }
839
840 // everything's fine if existing service entry supports the one
841 // to be registered
842 if (! is_supported_service( service_name, xExistingService_td ))
843 {
844 throw registry::CannotRegisterImplementationException(
845 "existing singleton service (" + singleton_name + "=" + existing_name + ") "
846 " does not support given one: " + service_name);
847 }
848 }
849 catch (const container::NoSuchElementException & exc)
850 {
851 css::uno::Any anyEx = cppu::getCaughtException();
852 throw css::lang::WrappedTargetRuntimeException(
853 "cannot get service type description: " + exc.Message,
854 nullptr, anyEx );
855 }
856 }
857 }
858 catch (registry::InvalidValueException &)
859 {
860 // repair
861 xKey2->setStringValue( service_name );
862 }
863 }
864 else
865 {
866 // insert singleton entry
867 xKey2 = xDest->getRootKey()->createKey( keyname );
868 xKey2->setStringValue( service_name );
869 }
870
871 Reference< registry::XRegistryKey > xRegisteredImplNames(
872 xKey2->openKey( "REGISTERED_BY" ) );
873 if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
874 {
875 // create
876 xRegisteredImplNames = xKey2->createKey( "REGISTERED_BY" );
877 }
878
879 Sequence< OUString > implnames;
880 try
881 {
882 implnames = xRegisteredImplNames->getAsciiListValue();
883 }
884 catch (registry::InvalidValueException &)
885 {
886 }
887 // check implname is already in
888 if (comphelper::findValue(implnames, implname) == -1)
889 {
890 // append and write back
891 implnames.realloc( implnames.getLength() +1 );
892 implnames.getArray()[ implnames.getLength() -1 ] = implname;
893 xRegisteredImplNames->setAsciiListValue( implnames );
894 }
895 }
896}
897
898
899// static prepareRegistry
900
901void prepareRegistry(
902 const Reference < XSimpleRegistry >& xDest,
903 const Reference < XRegistryKey >& xSource,
904 const OUString& implementationLoaderUrl,
905 const OUString& locationUrl,
906 Reference< XComponentContext > const & xContext )
907 // throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
908{
909 const Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
910
911 if (!subKeys.hasElements())
912 {
913 throw InvalidRegistryException(
914 "prepareRegistry(): source registry is empty" );
915 }
916
917 for (const Reference < XRegistryKey >& xImplKey : subKeys)
918 {
919 Reference < XRegistryKey > xKey = xImplKey->openKey(
920 slash_UNO_slash_SERVICES );
921
922 if (xKey.is())
923 {
924 // update entries in SERVICES section
925 const Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
926
927 OUString implName = xImplKey->getKeyName().copy(1);
928 sal_Int32 firstDot = implName.indexOf('/');
929
930 if (firstDot >= 0)
931 implName = implName.copy(firstDot + 1);
932
933 sal_Int32 offset = xKey->getKeyName().getLength() + 1;
934
935 for (const Reference < XRegistryKey >& rServiceKey : serviceKeys)
936 {
937 OUString serviceName = rServiceKey->getKeyName().copy(offset);
938
939 createUniqueSubEntry(
940 xDest->getRootKey()->createKey(
941 slash_SERVICES + serviceName ),
942 implName);
943 }
944
945 xKey = xImplKey->openKey( slash_UNO );
946 if (xKey.is())
947 {
948 const Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
949
950 for (const Reference < XRegistryKey >& rSubKey2 : subKeys2)
951 {
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 ))
955 {
956 prepareUserKeys(xDest, xKey, rSubKey2, implName, true);
957 }
958 }
959 }
960 }
961
962 // update LOCATION entry
963 xKey = xImplKey->createKey( slash_UNO_slash_LOCATION );
964
965 if (xKey.is())
966 {
967 xKey->setAsciiValue(locationUrl);
968 }
969
970 // update ACTIVATOR entry
971 xKey = xImplKey->createKey( slash_UNO_slash_ACTIVATOR );
972
973 if (xKey.is())
974 {
975 xKey->setAsciiValue(implementationLoaderUrl);
976 }
977
978 xKey = xImplKey->openKey( slash_UNO_slash_SERVICES );
979
980 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
981 {
982 // update link entries in REGISTRY_LINKS section
983 const Sequence<OUString> linkNames = xKey->getAsciiListValue();
984
985 for (const OUString& rLinkName : linkNames)
986 {
987 prepareLink(xDest, xImplKey, rLinkName);
988 }
989 }
990
991 insert_singletons( xDest, xImplKey, xContext );
992 }
993}
994
995
996void findImplementations( const Reference < XRegistryKey > & xSource,
997 std::vector<OUString>& implNames)
998{
999 bool isImplKey = false;
1000
1001 try
1002 {
1003 Reference < XRegistryKey > xKey = xSource->openKey(
1004 slash_UNO_slash_SERVICES );
1005
1006 if (xKey.is() && xKey->getKeyNames().hasElements())
1007 {
1008 isImplKey = true;
1009
1010 OUString implName = xSource->getKeyName().copy(1).replace('/', '.');
1011 sal_Int32 firstDot = implName.indexOf('.');
1012
1013 if (firstDot >= 0)
1014 implName = implName.copy(firstDot + 1);
1015
1016 implNames.push_back(implName);
1017 }
1018 }
1019 catch(InvalidRegistryException&)
1020 {
1021 }
1022
1023 if (isImplKey) return;
1024
1025 try
1026 {
1027 const Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1028
1029 for (const Reference < XRegistryKey >& rSubKey : subKeys)
1030 {
1031 findImplementations(rSubKey, implNames);
1032 }
1033 }
1034 catch(InvalidRegistryException&)
1035 {
1036 }
1037}
1038
1039
1040class ImplementationRegistration
1041 : public WeakImplHelper< XImplementationRegistration2, XServiceInfo, XInitialization >
1042{
1043public:
1044 explicit ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
1045
1046 // XServiceInfo
1047 OUString SAL_CALL getImplementationName() override;
1048 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
1049 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
1050
1051 // XImplementationRegistration
1052 virtual void SAL_CALL registerImplementation(
1053 const OUString& implementationLoader,
1054 const OUString& location,
1055 const Reference < XSimpleRegistry > & xReg) override;
1056
1057 virtual sal_Bool SAL_CALL revokeImplementation(
1058 const OUString& location,
1059 const Reference < XSimpleRegistry >& xReg) override;
1060
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;
1066
1067 // XImplementationRegistration2
1068 virtual void SAL_CALL registerImplementationWithLocation(
1069 const OUString& implementationLoader,
1070 const OUString& location,
1071 const OUString& registeredLocation,
1072 const Reference < XSimpleRegistry > & xReg) override;
1073
1074 // XInitialization
1075 virtual void SAL_CALL initialize(
1076 const css::uno::Sequence< css::uno::Any >& aArguments ) override;
1077
1078private: // helper methods
1079 void prepareRegister(
1080 const OUString& implementationLoader,
1081 const OUString& location,
1082 const OUString& registeredLocation,
1083 const Reference < XSimpleRegistry > & xReg);
1084 // throw( CannotRegisterImplementationException, RuntimeException )
1085
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);
1093 /* throw ( InvalidRegistryException,
1094 MergeConflictException,
1095 CannotRegisterImplementationException, RuntimeException ) */
1096
1097 static void doRevoke( const Reference < XSimpleRegistry >& xDest,
1098 std::u16string_view locationUrl );
1099 // throw( InvalidRegistryException, RuntimeException )
1100 Reference< XSimpleRegistry > getRegistryFromServiceManager() const;
1101
1102 static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
1103 const Reference< XMultiComponentFactory > &rSMgr,
1104 const Reference < XComponentContext > & rCtx );
1105
1106private: // members
1107 Reference < XMultiComponentFactory > m_xSMgr;
1108 Reference < XComponentContext > m_xCtx;
1109};
1110
1111
1112// ImplementationRegistration()
1113
1114ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
1115 : m_xSMgr( xCtx->getServiceManager() )
1116 , m_xCtx( xCtx )
1117{}
1118
1119// XServiceInfo
1120OUString ImplementationRegistration::getImplementationName()
1121{
1122 return "com.sun.star.comp.stoc.ImplementationRegistration";
1123}
1124
1125// XServiceInfo
1126sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName)
1127{
1128 return cppu::supportsService(this, ServiceName);
1129}
1130
1131// XServiceInfo
1132Sequence< OUString > ImplementationRegistration::getSupportedServiceNames()
1133{
1134 return { "com.sun.star.registry.ImplementationRegistration" };
1135}
1136
1137Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager() const
1138{
1139 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1140 Reference < XSimpleRegistry > xRegistry;
1141
1142 if( xPropSet.is() ) {
1143
1144 try { // the implementation does not support XIntrospectionAccess !
1145
1146 Any aAny = xPropSet->getPropertyValue( Registry );
1147
1148 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1149 aAny >>= xRegistry;
1150 }
1151 }
1152 catch( UnknownPropertyException & ) {
1153 // empty reference is error signal !
1154 }
1155 }
1156
1157 return xRegistry;
1158}
1159
1160
1161// XInitialization
1162
1163void ImplementationRegistration::initialize(
1164 const css::uno::Sequence< css::uno::Any >& aArgs )
1165{
1166
1167 if( aArgs.getLength() != 4 ) {
1168 throw IllegalArgumentException(
1169 "ImplementationRegistration::initialize() expects 4 parameters, got " + OUString::number( aArgs.getLength() ),
1170 Reference<XInterface > (), 0 );
1171 }
1172
1173 Reference< XImplementationLoader > rLoader;
1174 OUString loaderServiceName;
1175 OUString locationUrl;
1176 Reference< XSimpleRegistry > rReg;
1177
1178 // 1st argument : An instance of an implementation loader
1179 if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1180 aArgs.getConstArray()[0] >>= rLoader;
1181 }
1182 if( !rLoader.is()) {
1183 throw IllegalArgumentException(
1184 "ImplementationRegistration::initialize() invalid first parameter,"
1185 "expected " + cppu::UnoType<decltype(rLoader)>::get().getTypeName() +
1186 ", got " + aArgs.getConstArray()[0].getValueTypeName(),
1187 Reference< XInterface > (), 0 );
1188 }
1189
1190 // 2nd argument : The service name of the loader. This name is written into the registry
1191 if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
1192 aArgs.getConstArray()[1] >>= loaderServiceName;
1193 }
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 );
1199 }
1200
1201 // 3rd argument : The file name of the dll, that contains the loader
1202 if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
1203 aArgs.getConstArray()[2] >>= locationUrl;
1204 }
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 );
1210 }
1211
1212 // 4th argument : The registry, the service should be written to
1213 if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1214 aArgs.getConstArray()[3] >>= rReg;
1215 }
1216
1217 if( !rReg.is() ) {
1218 rReg = getRegistryFromServiceManager();
1219 if( !rReg.is() ) {
1220 throw IllegalArgumentException(
1221 "ImplementationRegistration::initialize() invalid fourth parameter,"
1222 "expected " + cppu::UnoType<decltype(rReg)>::get().getTypeName() +
1223 ", got " + aArgs.getConstArray()[3].getValueTypeName(),
1224 Reference< XInterface > (), 0 );
1225 }
1226 }
1227
1228 doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
1229}
1230
1231
1232// virtual function registerImplementationWithLocation of XImplementationRegistration2
1233
1234void ImplementationRegistration::registerImplementationWithLocation(
1235 const OUString& implementationLoaderUrl,
1236 const OUString& locationUrl,
1237 const OUString& registeredLocationUrl,
1238 const Reference < XSimpleRegistry > & xReg)
1239{
1240 prepareRegister(
1241 implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
1242}
1243
1244// helper function
1245void ImplementationRegistration::prepareRegister(
1246 const OUString& implementationLoaderUrl,
1247 const OUString& locationUrl,
1248 const OUString& registeredLocationUrl,
1249 const Reference < XSimpleRegistry > & xReg)
1250 // throw( CannotRegisterImplementationException, RuntimeException )
1251{
1252 OUString activatorName;
1253
1254 if (!implementationLoaderUrl.isEmpty())
1255 {
1256 activatorName = implementationLoaderUrl.getToken(0, ':');
1257 } else
1258 {
1259 // check locationUrl to find out what kind of loader is needed
1260 // set implLoaderUrl
1261 }
1262
1263 if( !m_xSMgr.is() ) {
1264 throw CannotRegisterImplementationException(
1265 "ImplementationRegistration::registerImplementation() "
1266 "no componentcontext available to instantiate loader" );
1267 }
1268
1269 try
1270 {
1271 Reference < XImplementationLoader > xAct(
1272 m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1273 if (!xAct.is())
1274 {
1275 throw CannotRegisterImplementationException(
1276 "ImplementationRegistration::registerImplementation() - The service "
1277 + activatorName + " cannot be instantiated" );
1278 }
1279
1280 Reference < XSimpleRegistry > xRegistry;
1281
1282 if (xReg.is())
1283 {
1284 // registry supplied by user
1285 xRegistry = xReg;
1286 }
1287 else
1288 {
1289 xRegistry = getRegistryFromServiceManager();
1290 }
1291
1292 if ( xRegistry.is())
1293 {
1294 doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implementationLoaderUrl,
1295 locationUrl, registeredLocationUrl);
1296 }
1297
1298 }
1299 catch( CannotRegisterImplementationException & )
1300 {
1301 throw;
1302 }
1303 catch( const InvalidRegistryException & e )
1304 {
1305 throw CannotRegisterImplementationException(
1306 "ImplementationRegistration::registerImplementation() "
1307 "InvalidRegistryException during registration (" + e.Message + ")" );
1308 }
1309 catch( const MergeConflictException & e )
1310 {
1311 throw CannotRegisterImplementationException(
1312 "ImplementationRegistration::registerImplementation() "
1313 "MergeConflictException during registration (" + e.Message + ")" );
1314 }
1315
1316}
1317
1318
1319// virtual function registerImplementation of XImplementationRegistration
1320
1321void ImplementationRegistration::registerImplementation(
1322 const OUString& implementationLoaderUrl,
1323 const OUString& locationUrl,
1324 const Reference < XSimpleRegistry > & xReg)
1325{
1326 prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1327}
1328
1329
1330// virtual function revokeImplementation of XImplementationRegistration
1331
1332sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
1333 const Reference < XSimpleRegistry >& xReg)
1334{
1335 bool ret = false;
1336
1337 Reference < XSimpleRegistry > xRegistry;
1338
1339 if (xReg.is()) {
1340 xRegistry = xReg;
1341 }
1342 else {
1343 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1344 if( xPropSet.is() ) {
1345 try {
1346 Any aAny = xPropSet->getPropertyValue( Registry );
1347
1348 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
1349 {
1350 aAny >>= xRegistry;
1351 }
1352 }
1353 catch ( UnknownPropertyException & ) {
1354 }
1355 }
1356 }
1357
1358 if (xRegistry.is())
1359 {
1360 try
1361 {
1362 doRevoke(xRegistry, location);
1363 ret = true;
1364 }
1365 catch( InvalidRegistryException & )
1366 {
1367 // no way to transport the error, as no exception is specified and a runtime
1368 // exception is not appropriate.
1369 OSL_FAIL( "InvalidRegistryException during revokeImplementation" );
1370 }
1371 }
1372
1373 return ret;
1374}
1375
1376
1377// virtual function getImplementations of XImplementationRegistration
1378
1379Sequence< OUString > ImplementationRegistration::getImplementations(
1380 const OUString & implementationLoaderUrl,
1381 const OUString & locationUrl)
1382{
1383 OUString activatorName;
1384
1385 if (!implementationLoaderUrl.isEmpty())
1386 {
1387 activatorName = implementationLoaderUrl.getToken(0, ':');
1388 } else
1389 {
1390 // check locationUrl to find out what kind of loader is needed
1391 // set implementationLoaderUrl
1392 }
1393
1394 if( m_xSMgr.is() ) {
1395
1396 Reference < XImplementationLoader > xAct(
1397 m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1398
1399 if (xAct.is())
1400 {
1401
1402 Reference < XSimpleRegistry > xReg =
1403 createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1404
1405 if (xReg.is())
1406 {
1407 try
1408 {
1409 xReg->open(OUString() /* in mem */, false, true);
1410 Reference < XRegistryKey > xImpl;
1411
1412 { // only necessary for deleting the temporary variable of rootkey
1413 xImpl = xReg->getRootKey()->createKey( slash_IMPLEMENTATIONS );
1414 }
1415 if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1416 {
1417 std::vector<OUString> implNames;
1418
1419 findImplementations(xImpl, implNames);
1420
1421 if (!implNames.empty())
1422 {
1423 Sequence<OUString> seqImpl(comphelper::containerToSequence(implNames));
1424 xImpl->closeKey();
1425 return seqImpl;
1426 }
1427 }
1428
1429 xImpl->closeKey();
1430 }
1431 catch(MergeConflictException&)
1432 {
1433 }
1434 catch(InvalidRegistryException&)
1435 {
1436 }
1437 }
1438 }
1439 }
1440
1441 return Sequence<OUString>();
1442}
1443
1444
1445// virtual function checkInstantiation of XImplementationRegistration
1446
1447Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
1448{
1449 OSL_FAIL( "ImplementationRegistration::checkInstantiation not implemented" );
1450 return Sequence<OUString>();
1451}
1452
1453
1454// helper function doRegistration
1455
1456
1457void ImplementationRegistration::doRevoke(
1458 const Reference < XSimpleRegistry >& xDest,
1459 std::u16string_view locationUrl)
1460 // throw ( InvalidRegistryException, RuntimeException )
1461{
1462 if( !xDest.is() )
1463 return;
1464
1465 std::vector<OUString> aNames;
1466
1467 Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1468
1469 Reference < XRegistryKey > xKey =
1470 xRootKey->openKey( slash_IMPLEMENTATIONS );
1471 if (xKey.is() && xKey->isValid())
1472 {
1473 deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1474 }
1475
1476 xKey = xRootKey->openKey( slash_SERVICES );
1477 if (xKey.is())
1478 {
1479 for (auto const& name : aNames)
1480 {
1481 deleteAllServiceEntries(xDest, xKey, name);
1482 }
1483 }
1484
1485 xKey = xRootKey->openKey( "/SINGLETONS" );
1486 if (xKey.is() && xKey->isValid())
1487 {
1488 delete_all_singleton_entries( xKey, aNames );
1489 }
1490
1491 if (xRootKey.is())
1492 xRootKey->closeKey();
1493 if (xKey.is() && xKey->isValid() )
1494 xKey->closeKey();
1495}
1496
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)
1505 /* throw ( InvalidRegistryException,
1506 MergeConflictException,
1507 CannotRegisterImplementationException, RuntimeException ) */
1508{
1509 Reference < XSimpleRegistry > xReg =
1510 createTemporarySimpleRegistry( xSMgr, xCtx );
1511 Reference < XRegistryKey > xSourceKey;
1512
1513 if (!(xAct.is() && xReg.is() && xDest.is()))
1514 return;
1515
1516 try
1517 {
1518 xReg->open(OUString() /* in mem */, false, true);
1519
1520 { // only necessary for deleting the temporary variable of rootkey
1521 xSourceKey = xReg->getRootKey()->createKey( slash_IMPLEMENTATIONS );
1522 }
1523
1524 bool bSuccess =
1525 xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1526 if ( !bSuccess )
1527 {
1528 throw CannotRegisterImplementationException(
1529 "ImplementationRegistration::doRegistration() component registration signaled failure" );
1530 }
1531
1532 prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1533
1534 xSourceKey->closeKey();
1535
1536 xSourceKey = xReg->getRootKey();
1537 Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1538 stoc_impreg::mergeKeys( xDestKey, xSourceKey );
1539 xDestKey->closeKey();
1540 xSourceKey->closeKey();
1541
1542
1543 // Cleanup Source registry.
1544 if ( xSourceKey->isValid() )
1545 xSourceKey->closeKey();
1546 }
1547 catch(CannotRegisterImplementationException&)
1548 {
1549 if ( xSourceKey->isValid() )
1550 xSourceKey->closeKey();
1551 // and throw again
1552 throw;
1553 }
1554}
1555
1556
1557Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1558 const Reference< XMultiComponentFactory > &rSMgr,
1559 const Reference < XComponentContext > & xCtx)
1560{
1561
1562 Reference < XSimpleRegistry > xReg(
1563 rSMgr->createInstanceWithContext(
1564 com_sun_star_registry_SimpleRegistry, xCtx ),
1565 UNO_QUERY);
1566 OSL_ASSERT( xReg.is() );
1567 return xReg;
1568}
1569
1570}
1571
1572extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1574 css::uno::XComponentContext *context,
1575 css::uno::Sequence<css::uno::Any> const &)
1576{
1577 return cppu::acquire(new ImplementationRegistration(context));
1578}
1579
1580/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XComponentContext > m_xCtx
Reference< lang::XMultiComponentFactory > m_xSMgr
Any value
float u
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 &)
Definition: implreg.cxx:1573
sal_Int32 nIndex
Definition: invocation.cxx:697
void * p
sal_Int64 n
sal_uInt16 nPos
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()
int i
constexpr OUStringLiteral first
static void mergeKeys(Reference< registry::XRegistryKey > const &xDest, Reference< registry::XRegistryKey > const &xSource, t_links &links)
Definition: mergekeys.cxx:55
SwNodeOffset abs(const SwNodeOffset &a)
const char * implName
unsigned char sal_Bool
sal_uInt16 sal_Unicode