Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / stoc / source / implementationregistration / implreg.cxx
blobd32de8ff99d6d14432904183f5dc728c1d1fd9ea
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <stdlib.h>
21 #include <string.h>
22 #include <list>
24 #include <cppuhelper/queryinterface.hxx>
25 #include <cppuhelper/weak.hxx>
26 #include <cppuhelper/implbase.hxx>
27 #include <cppuhelper/implementationentry.hxx>
28 #include <cppuhelper/supportsservice.hxx>
29 #include <comphelper/sequence.hxx>
31 #include <uno/mapping.hxx>
32 #include <osl/thread.h>
34 #include <rtl/ref.hxx>
35 #include <rtl/ustring.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <osl/process.h>
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/lang/XInitialization.hpp>
41 #include <com/sun/star/loader/XImplementationLoader.hpp>
42 #include <com/sun/star/registry/XImplementationRegistration2.hpp>
43 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
44 #include <com/sun/star/reflection/XServiceTypeDescription.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/uno/RuntimeException.hpp>
48 #include "mergekeys.hxx"
50 #if defined(SAL_W32)
51 #include <io.h>
52 #else
53 #include <unistd.h>
54 #endif
57 using namespace com::sun::star;
58 using namespace css::uno;
59 using namespace css::loader;
60 using namespace css::beans;
61 using namespace css::lang;
62 using namespace css::registry;
63 using namespace cppu;
64 using namespace osl;
66 namespace {
68 struct StringPool
70 OUString slash_UNO_slash_REGISTRY_LINKS;
71 OUString slash_IMPLEMENTATIONS;
72 OUString slash_UNO;
73 OUString slash_UNO_slash_SERVICES;
74 OUString slash_UNO_slash_SINGLETONS;
75 OUString slash_SERVICES;
76 OUString slash_UNO_slash_LOCATION;
77 OUString slash_UNO_slash_ACTIVATOR;
78 OUString colon_old;
79 OUString com_sun_star_registry_SimpleRegistry;
80 OUString Registry;
81 StringPool()
82 : slash_UNO_slash_REGISTRY_LINKS( "/UNO/REGISTRY_LINKS")
83 , slash_IMPLEMENTATIONS( "/IMPLEMENTATIONS" )
84 , slash_UNO( "/UNO")
85 , slash_UNO_slash_SERVICES( "/UNO/SERVICES")
86 , slash_UNO_slash_SINGLETONS( "/UNO/SINGLETONS")
87 , slash_SERVICES( "/SERVICES/" )
88 , slash_UNO_slash_LOCATION( "/UNO/LOCATION" )
89 , slash_UNO_slash_ACTIVATOR( "/UNO/ACTIVATOR" )
90 , colon_old( ":old")
91 , com_sun_star_registry_SimpleRegistry("com.sun.star.registry.SimpleRegistry" )
92 , Registry( "Registry" )
94 StringPool(const StringPool&) = delete;
95 StringPool& operator=(const StringPool&) = delete;
98 const StringPool &spool()
100 static StringPool *pPool = nullptr;
101 if( ! pPool )
103 MutexGuard guard( Mutex::getGlobalMutex() );
104 if( ! pPool )
106 static StringPool pool;
107 pPool = &pool;
110 return *pPool;
114 // static deleteAllLinkReferences()
116 void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
117 const Reference < XRegistryKey >& xSource)
118 // throw ( InvalidRegistryException, RuntimeException )
120 Reference < XRegistryKey > xKey = xSource->openKey(
121 spool().slash_UNO_slash_REGISTRY_LINKS );
123 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
125 Sequence<OUString> linkNames = xKey->getAsciiListValue();
127 if (linkNames.getLength())
129 const OUString* pLinkNames = linkNames.getConstArray();
131 OUString aLinkName;
132 OUString aLinkParent;
133 Reference < XRegistryKey > xLinkParent;
134 const sal_Unicode* pTmpName = nullptr;
135 const sal_Unicode* pShortName = nullptr;
136 sal_Int32 sEnd = 0;
138 for (sal_Int32 i = 0; i < linkNames.getLength(); i++)
140 aLinkName = pLinkNames[i];
142 pTmpName = aLinkName.getStr();
144 if (pTmpName[0] != L'/')
145 continue;
147 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
148 if ( nIndex == -1 )
149 pShortName = nullptr;
150 else
151 pShortName = pTmpName+nIndex;
153 while (pShortName && pShortName[1] == L'%')
155 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
156 if ( nIndex == -1 )
157 pShortName = nullptr;
158 else
159 pShortName += nIndex+2;
162 if (pShortName)
164 aLinkName = aLinkName.copy(0, pShortName - pTmpName);
167 xReg->getRootKey()->deleteLink(aLinkName);
169 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
171 aLinkParent = aLinkName.copy(0, sEnd);
173 while(!aLinkParent.isEmpty())
175 xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
177 if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0))
179 aLinkName = aLinkParent;
181 xReg->getRootKey()->deleteKey(aLinkParent);
183 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
185 aLinkParent = aLinkName.copy(0, sEnd);
186 } else
188 break;
197 // static prepareLink
199 void prepareLink( const Reference < XSimpleRegistry > & xDest,
200 const Reference < XRegistryKey > & xSource,
201 const OUString& link)
202 // throw ( InvalidRegistryException, RuntimeException )
204 OUString linkRefName = xSource->getKeyName();
205 OUString linkName(link);
206 bool isRelativ = false;
208 const sal_Unicode* pTmpName = link.getStr();
209 const sal_Unicode* pShortName;
210 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
211 if ( nIndex == -1 )
212 pShortName = nullptr;
213 else
214 pShortName = pTmpName+nIndex;
216 if (pTmpName[0] != L'/')
217 isRelativ = true;
219 while (pShortName && pShortName[1] == L'%')
221 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
222 if ( nIndex == -1 )
223 pShortName = nullptr;
224 else
225 pShortName += nIndex+2;
228 if (pShortName)
230 linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1);
231 linkName = link.copy(0, pShortName - pTmpName);
234 if (isRelativ)
235 xSource->createLink(linkName, linkRefName);
236 else
237 xDest->getRootKey()->createLink(linkName, linkRefName);
241 // static searchImplForLink
243 OUString searchImplForLink(
244 const Reference < XRegistryKey > & xRootKey,
245 const OUString& linkName,
246 const OUString& implName )
247 // throw ( InvalidRegistryException, RuntimeException )
249 const StringPool & pool = spool();
250 Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
251 if (xKey.is())
253 Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
254 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
255 OUString key_name( pool.slash_UNO + linkName );
257 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
261 Reference < XRegistryKey > xImplKey( pSubKeys[i] );
262 if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
264 OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
265 if (implName != oldImplName)
267 return oldImplName;
271 catch(InvalidRegistryException&)
277 return OUString();
281 // static searchLinkTargetForImpl
283 OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
284 const OUString& linkName,
285 const OUString& implName)
286 // throw ( InvalidRegistryException, RuntimeException )
288 OUString ret;
290 // try
291 // {
292 const StringPool & pool = spool();
293 Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
295 if (xKey.is())
297 Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
299 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
300 Reference < XRegistryKey > xImplKey;
302 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
304 xImplKey = pSubKeys[i];
306 OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
307 OUString qualifiedLinkName( pool.slash_UNO );
308 qualifiedLinkName += linkName;
309 if (tmpImplName == implName &&
310 xImplKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK)
312 return xImplKey->getLinkTarget( qualifiedLinkName );
316 // }
317 // catch(InvalidRegistryException&)
318 // {
319 // }
321 return ret;
325 // static createUniqueSubEntry
327 void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
328 const OUString& value)
329 // throw ( InvalidRegistryException, RuntimeException )
331 if (xSuperKey.is())
333 // try
334 // {
335 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
337 sal_Int32 length = 0;
338 bool bReady = false;
340 Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
341 length = implEntries.getLength();
343 for (sal_Int32 i = 0; !bReady && (i < length); i++)
345 bReady = (implEntries.getConstArray()[i] == value);
348 if (bReady)
350 Sequence<OUString> implEntriesNew(length);
351 implEntriesNew.getArray()[0] = value;
353 for (sal_Int32 i=0, j=1; i < length; i++)
355 if (implEntries.getConstArray()[i] != value)
356 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
358 xSuperKey->setAsciiListValue(implEntriesNew);
359 } else
361 Sequence<OUString> implEntriesNew(length+1);
362 implEntriesNew.getArray()[0] = value;
364 for (sal_Int32 i = 0; i < length; i++)
366 implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i];
368 xSuperKey->setAsciiListValue(implEntriesNew);
370 } else
372 Sequence<OUString> implEntriesNew { value };
374 xSuperKey->setAsciiListValue(implEntriesNew);
376 // }
377 // catch(InvalidRegistryException&)
378 // {
379 // }
384 // static deleteSubEntry
386 bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value)
387 // throw ( InvalidRegistryException, RuntimeException )
389 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
391 Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
392 sal_Int32 length = implEntries.getLength();
393 sal_Int32 equals = 0;
394 bool hasNoImplementations = false;
396 for (sal_Int32 i = 0; i < length; i++)
398 if (implEntries.getConstArray()[i] == value)
399 equals++;
402 if (equals == length)
404 hasNoImplementations = true;
405 } else
407 Sequence<OUString> implEntriesNew(length - equals);
409 sal_Int32 j = 0;
410 for (sal_Int32 i = 0; i < length; i++)
412 if (implEntries.getConstArray()[i] != value)
414 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
417 xSuperKey->setAsciiListValue(implEntriesNew);
420 if (hasNoImplementations)
422 return true;
425 return false;
429 // static prepareUserLink
431 void prepareUserLink(const Reference < XSimpleRegistry >& xDest,
432 const OUString& linkName,
433 const OUString& linkTarget,
434 const OUString& implName)
436 Reference < XRegistryKey > xRootKey;
438 xRootKey = xDest->getRootKey();
440 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
442 OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
444 if (!oldImplName.isEmpty())
446 createUniqueSubEntry(xDest->getRootKey()->createKey(
447 linkName + spool().colon_old ), oldImplName);
451 if (xRootKey->isValid())
452 xRootKey->createLink(linkName, linkTarget);
456 // static deleteUserLink
458 void deletePathIfPossible(const Reference < XRegistryKey >& xRootKey,
459 const OUString& path)
463 Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
465 if (keyNames.getLength() == 0 &&
466 xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
468 xRootKey->deleteKey(path);
470 OUString newPath = path.copy(0, path.lastIndexOf('/'));
472 if (newPath.getLength() > 1)
473 deletePathIfPossible(xRootKey, newPath);
476 catch(InvalidRegistryException&)
482 // static deleteUserLink
484 void deleteUserLink(const Reference < XRegistryKey >& xRootKey,
485 const OUString& linkName,
486 const OUString& linkTarget,
487 const OUString& implName)
488 // throw ( InvalidRegistryException, RuntimeException )
490 bool bClean = false;
492 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
494 OUString tmpTarget = xRootKey->getLinkTarget(linkName);
496 if (tmpTarget == linkTarget)
498 xRootKey->deleteLink(linkName);
502 Reference < XRegistryKey > xOldKey = xRootKey->openKey(
503 linkName + spool().colon_old );
504 if (xOldKey.is())
506 if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
508 Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
509 sal_Int32 length = implEntries.getLength();
510 sal_Int32 equals = 0;
511 bool hasNoImplementations = false;
513 for (sal_Int32 i = 0; i < length; i++)
515 if (implEntries.getConstArray()[i] == implName)
516 equals++;
519 if (equals == length)
521 hasNoImplementations = true;
522 } else
524 OUString oldImpl;
526 if (length > equals + 1)
528 Sequence<OUString> implEntriesNew(length - equals - 1);
530 sal_Int32 j = 0;
531 bool first = true;
532 for (sal_Int32 i = 0; i < length; i++)
534 if (implEntries.getConstArray()[i] != implName)
536 if (first)
538 oldImpl = implEntries.getConstArray()[i];
539 first = false;
540 } else
542 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
547 xOldKey->setAsciiListValue(implEntriesNew);
548 } else
550 oldImpl = implEntries.getConstArray()[0];
551 OUString path(xOldKey->getKeyName());
552 xOldKey->closeKey();
553 xRootKey->deleteKey(path);
556 OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
557 if (!oldTarget.isEmpty())
559 xRootKey->createLink(linkName, oldTarget);
563 if (hasNoImplementations)
565 bClean = true;
566 OUString path(xOldKey->getKeyName());
567 xOldKey->closeKey();
568 xRootKey->deleteKey(path);
571 } else
573 bClean = true;
576 if (bClean)
578 OUString path = linkName.copy(0, linkName.lastIndexOf('/'));
579 deletePathIfPossible(xRootKey, path);
584 // static prepareUserKeys
586 void prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
587 const Reference < XRegistryKey >& xUnoKey,
588 const Reference < XRegistryKey >& xKey,
589 const OUString& implName,
590 bool bRegister)
592 bool hasSubKeys = false;
594 Sequence<OUString> keyNames = xKey->getKeyNames();
596 OUString relativKey;
597 if (keyNames.getLength())
598 relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
600 if (keyNames.getLength() == 1 &&
601 xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
603 hasSubKeys = true;
605 OUString linkTarget = xKey->getLinkTarget(relativKey);
606 OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
608 linkName = linkName + "/" + relativKey;
610 if (bRegister)
612 prepareUserLink(xDest, linkName, linkTarget, implName);
613 } else
615 deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
617 } else
619 Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
621 if (subKeys.getLength())
623 hasSubKeys = true;
624 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
626 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
628 prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
633 if (! hasSubKeys)
635 OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
637 Reference < XRegistryKey > xRootKey = xDest->getRootKey();
638 if (bRegister)
640 createUniqueSubEntry(xRootKey->createKey(keyName), implName);
642 else
644 Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
645 if( rKey.is() )
647 deleteSubEntry(rKey, implName);
648 xRootKey->deleteKey(keyName);
651 OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
652 if( !path.isEmpty() )
654 deletePathIfPossible(xRootKey, path);
661 // static deleteAllImplementations
663 void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg,
664 const Reference < XRegistryKey >& xSource,
665 const OUString& locationUrl,
666 std::list<OUString> & implNames)
667 // throw (InvalidRegistryException, RuntimeException)
669 Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
671 if (subKeys.getLength() > 0)
673 const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
674 Reference < XRegistryKey > xImplKey;
675 bool hasLocationUrl = false;
677 const StringPool &pool = spool();
678 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
680 xImplKey = pSubKeys[i];
681 Reference < XRegistryKey > xKey = xImplKey->openKey(
682 pool.slash_UNO_slash_LOCATION );
684 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
686 if (xKey->getAsciiValue() == locationUrl)
688 hasLocationUrl = true;
690 OUString implName(xImplKey->getKeyName().getStr() + 1);
691 sal_Int32 firstDot = implName.indexOf('/');
693 if (firstDot >= 0)
694 implName = implName.copy(firstDot + 1);
696 implNames.push_back(implName);
698 deleteAllLinkReferences(xReg, xImplKey);
700 xKey = xImplKey->openKey( pool.slash_UNO );
701 if (xKey.is())
703 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
705 if (subKeys2.getLength())
707 const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
709 for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
711 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
712 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
713 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
714 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
715 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
717 prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, false);
725 if (hasLocationUrl)
727 hasLocationUrl = false;
728 OUString path(xImplKey->getKeyName());
729 xImplKey->closeKey();
730 xReg->getRootKey()->deleteKey(path);
734 subKeys = xSource->openKeys();
735 if (subKeys.getLength() == 0)
737 OUString path(xSource->getKeyName());
738 xSource->closeKey();
739 xReg->getRootKey()->deleteKey(path);
741 } else
743 OUString path(xSource->getKeyName());
744 xSource->closeKey();
745 xReg->getRootKey()->deleteKey(path);
750 void delete_all_singleton_entries(
751 Reference < registry::XRegistryKey > const & xSingletons_section,
752 ::std::list< OUString > const & impl_names )
753 // throw (InvalidRegistryException, RuntimeException)
755 Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
756 Reference< registry::XRegistryKey > const * subkeys = singletons.getConstArray();
757 for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
759 Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
760 Reference< registry::XRegistryKey > xRegisteredImplNames(
761 xSingleton->openKey( "REGISTERED_BY" ) );
762 if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
764 Sequence< OUString > registered_implnames;
767 registered_implnames = xRegisteredImplNames->getAsciiListValue();
769 catch (registry::InvalidValueException &)
772 OUString const * p = registered_implnames.getConstArray();
773 sal_Int32 nOrigRegLength = registered_implnames.getLength();
774 sal_Int32 nNewLength = nOrigRegLength;
775 for ( sal_Int32 n = nOrigRegLength; n--; )
777 OUString const & registered_implname = p[ n ];
779 ::std::list< OUString >::const_iterator iPos( impl_names.begin() );
780 ::std::list< OUString >::const_iterator const iEnd( impl_names.end() );
781 for ( ; iPos != iEnd; ++iPos )
783 if (iPos->equals( registered_implname ))
785 registered_implnames[ n ] = p[ nNewLength -1 ];
786 --nNewLength;
791 if (nNewLength != nOrigRegLength)
793 if (0 == nNewLength)
795 // remove whole entry
796 xRegisteredImplNames->closeKey();
797 xSingleton->deleteKey( "REGISTERED_BY" );
798 // registry key cannot provide its relative name, only absolute :(
799 OUString abs( xSingleton->getKeyName() );
800 xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
802 else
804 registered_implnames.realloc( nNewLength );
805 xRegisteredImplNames->setAsciiListValue( registered_implnames );
813 // static deleteAllServiceEntries
815 void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg,
816 const Reference < XRegistryKey >& xSource,
817 const OUString& implName)
818 // throw ( InvalidRegistryException, RuntimeException )
820 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
822 if (subKeys.getLength() > 0)
824 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
825 Reference < XRegistryKey > xServiceKey;
826 bool hasNoImplementations = false;
828 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
830 xServiceKey = pSubKeys[i];
832 if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
834 Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
835 sal_Int32 length = implEntries.getLength();
836 sal_Int32 equals = 0;
838 for (sal_Int32 j = 0; j < length; j++)
840 if (implEntries.getConstArray()[j] == implName)
841 equals++;
844 if (equals == length)
846 hasNoImplementations = true;
847 } else
849 if (equals > 0)
851 Sequence<OUString> implEntriesNew(length-equals);
853 sal_Int32 j = 0;
854 for (sal_Int32 k = 0; k < length; k++)
856 if (implEntries.getConstArray()[k] != implName)
858 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[k];
862 xServiceKey->setAsciiListValue(implEntriesNew);
867 if (hasNoImplementations)
869 hasNoImplementations = false;
870 OUString path(xServiceKey->getKeyName());
871 xServiceKey->closeKey();
872 xReg->getRootKey()->deleteKey(path);
876 subKeys = xSource->openKeys();
877 if (subKeys.getLength() == 0)
879 OUString path(xSource->getKeyName());
880 xSource->closeKey();
881 xReg->getRootKey()->deleteKey(path);
883 } else
885 OUString path(xSource->getKeyName());
886 xSource->closeKey();
887 xReg->getRootKey()->deleteKey(path);
892 bool is_supported_service(
893 OUString const & service_name,
894 Reference< reflection::XServiceTypeDescription > const & xService_td )
896 if (xService_td->getName().equals( service_name ))
897 return true;
898 Sequence< Reference< reflection::XServiceTypeDescription > > seq(
899 xService_td->getMandatoryServices() );
900 Reference< reflection::XServiceTypeDescription > const * p = seq.getConstArray();
901 for ( sal_Int32 nPos = seq.getLength(); nPos--; )
903 if (is_supported_service( service_name, p[ nPos ] ))
904 return true;
906 return false;
910 void insert_singletons(
911 Reference< registry::XSimpleRegistry > const & xDest,
912 Reference< registry::XRegistryKey > const & xImplKey,
913 Reference< XComponentContext > const & xContext )
914 // throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
916 // singletons
917 Reference< registry::XRegistryKey > xKey( xImplKey->openKey( "UNO/SINGLETONS" ) );
918 if (xKey.is() && xKey->isValid())
920 OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
921 // singleton entries
922 Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
923 Reference< registry::XRegistryKey > const * p = xSingletons_section.getConstArray();
924 for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
926 Reference< registry::XRegistryKey > const & xSingleton = p[ nPos ];
927 OUString singleton_name(
928 xSingleton->getKeyName().copy(
929 implname.getLength() + sizeof ("/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
930 OUString service_name( xSingleton->getStringValue() );
932 OUString keyname( "/SINGLETONS/" + singleton_name );
933 Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
934 if (xKey2.is() && xKey2->isValid())
938 OUString existing_name( xKey2->getStringValue() );
939 if (! existing_name.equals( service_name ))
941 Reference< container::XHierarchicalNameAccess > xTDMgr;
942 OUString the_tdmgr =
943 "/singletons/com.sun.star.reflection.theTypeDescriptionManager";
944 xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
945 if (! xTDMgr.is())
947 throw RuntimeException( "cannot get singleton " + the_tdmgr );
951 Reference< reflection::XServiceTypeDescription > xExistingService_td;
952 xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
953 if (! xExistingService_td.is())
955 throw RuntimeException( "cannot get service type description: " + existing_name );
958 // everything's fine if existing service entry supports the one
959 // to be registered
960 if (! is_supported_service( service_name, xExistingService_td ))
962 throw registry::CannotRegisterImplementationException(
963 "existing singleton service (" + singleton_name + "=" + existing_name + ") "
964 " does not support given one: " + service_name);
967 catch (const container::NoSuchElementException & exc)
969 throw RuntimeException(
970 "cannot get service type description: " + exc.Message );
974 catch (registry::InvalidValueException &)
976 // repair
977 xKey2->setStringValue( service_name );
980 else
982 // insert singleton entry
983 xKey2 = xDest->getRootKey()->createKey( keyname );
984 xKey2->setStringValue( service_name );
987 Reference< registry::XRegistryKey > xRegisteredImplNames(
988 xKey2->openKey( "REGISTERED_BY" ) );
989 if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
991 // create
992 xRegisteredImplNames = xKey2->createKey( "REGISTERED_BY" );
995 Sequence< OUString > implnames;
998 implnames = xRegisteredImplNames->getAsciiListValue();
1000 catch (registry::InvalidValueException &)
1003 // check implname is already in
1004 sal_Int32 nPos_implnames = implnames.getLength();
1005 OUString const * pImplnames = implnames.getConstArray();
1006 while (nPos_implnames--)
1008 if (implname.equals( pImplnames[ nPos_implnames ] ))
1009 break;
1011 if (nPos_implnames < 0)
1013 // append and write back
1014 implnames.realloc( implnames.getLength() +1 );
1015 implnames[ implnames.getLength() -1 ] = implname;
1016 xRegisteredImplNames->setAsciiListValue( implnames );
1023 // static prepareRegistry
1025 void prepareRegistry(
1026 const Reference < XSimpleRegistry >& xDest,
1027 const Reference < XRegistryKey >& xSource,
1028 const OUString& implementationLoaderUrl,
1029 const OUString& locationUrl,
1030 Reference< XComponentContext > const & xContext )
1031 // throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
1033 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1035 if (!subKeys.getLength())
1037 throw InvalidRegistryException(
1038 "prepareRegistry(): source registry is empty" );
1041 const StringPool & pool = spool();
1043 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1044 Reference < XRegistryKey > xImplKey;
1046 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1048 xImplKey = pSubKeys[i];
1050 Reference < XRegistryKey > xKey = xImplKey->openKey(
1051 pool.slash_UNO_slash_SERVICES );
1053 if (xKey.is())
1055 // update entries in SERVICES section
1056 Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
1057 const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
1059 OUString implName = OUString(xImplKey->getKeyName().getStr() + 1);
1060 sal_Int32 firstDot = implName.indexOf('/');
1062 if (firstDot >= 0)
1063 implName = implName.copy(firstDot + 1);
1065 sal_Int32 offset = xKey->getKeyName().getLength() + 1;
1067 for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
1069 OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
1071 createUniqueSubEntry(
1072 xDest->getRootKey()->createKey(
1073 pool.slash_SERVICES + serviceName ),
1074 implName);
1077 xKey = xImplKey->openKey( pool.slash_UNO );
1078 if (xKey.is())
1080 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
1082 if (subKeys2.getLength())
1084 const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
1086 for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
1088 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
1089 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
1090 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
1092 prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, true);
1099 // update LOCATION entry
1100 xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
1102 if (xKey.is())
1104 xKey->setAsciiValue(locationUrl);
1107 // update ACTIVATOR entry
1108 xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
1110 if (xKey.is())
1112 xKey->setAsciiValue(implementationLoaderUrl);
1115 xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
1117 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
1119 // update link entries in REGISTRY_LINKS section
1120 Sequence<OUString> linkNames = xKey->getAsciiListValue();
1122 if (linkNames.getLength())
1124 const OUString* pLinkNames = linkNames.getConstArray();
1126 for (sal_Int32 j = 0; j < linkNames.getLength(); j++)
1128 prepareLink(xDest, xImplKey, pLinkNames[j]);
1133 insert_singletons( xDest, xImplKey, xContext );
1138 void findImplementations( const Reference < XRegistryKey > & xSource,
1139 std::list <OUString>& implNames)
1141 bool isImplKey = false;
1145 Reference < XRegistryKey > xKey = xSource->openKey(
1146 spool().slash_UNO_slash_SERVICES );
1148 if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
1150 isImplKey = true;
1152 OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace('/', '.').getStr();
1153 sal_Int32 firstDot = implName.indexOf('.');
1155 if (firstDot >= 0)
1156 implName = implName.copy(firstDot + 1);
1158 implNames.push_back(implName);
1161 catch(InvalidRegistryException&)
1165 if (isImplKey) return;
1169 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1171 if (subKeys.getLength() > 0)
1173 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1175 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1177 findImplementations(pSubKeys[i], implNames);
1182 catch(InvalidRegistryException&)
1188 class ImplementationRegistration
1189 : public WeakImplHelper< XImplementationRegistration2, XServiceInfo, XInitialization >
1191 public:
1192 explicit ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
1194 // XServiceInfo
1195 OUString SAL_CALL getImplementationName() override;
1196 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override;
1197 Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
1199 // XImplementationRegistration
1200 virtual void SAL_CALL registerImplementation(
1201 const OUString& implementationLoader,
1202 const OUString& location,
1203 const Reference < XSimpleRegistry > & xReg) override;
1205 virtual sal_Bool SAL_CALL revokeImplementation(
1206 const OUString& location,
1207 const Reference < XSimpleRegistry >& xReg) override;
1209 virtual Sequence< OUString > SAL_CALL getImplementations(
1210 const OUString& implementationLoader,
1211 const OUString& location) override;
1212 virtual Sequence< OUString > SAL_CALL checkInstantiation(
1213 const OUString& implementationName) override;
1215 // XImplementationRegistration2
1216 virtual void SAL_CALL registerImplementationWithLocation(
1217 const OUString& implementationLoader,
1218 const OUString& location,
1219 const OUString& registeredLocation,
1220 const Reference < XSimpleRegistry > & xReg) override;
1222 // XInitialization
1223 virtual void SAL_CALL initialize(
1224 const css::uno::Sequence< css::uno::Any >& aArguments ) override;
1226 private: // helper methods
1227 void prepareRegister(
1228 const OUString& implementationLoader,
1229 const OUString& location,
1230 const OUString& registeredLocation,
1231 const Reference < XSimpleRegistry > & xReg);
1232 // throw( CannotRegisterImplementationException, RuntimeException )
1234 static void doRegister( const Reference < XMultiComponentFactory >& xSMgr,
1235 const Reference < XComponentContext > &xCtx,
1236 const Reference < XImplementationLoader >& xAct,
1237 const Reference < XSimpleRegistry >& xDest,
1238 const OUString& implementationLoaderUrl,
1239 const OUString& locationUrl,
1240 const OUString& registeredLocationUrl);
1241 /* throw ( InvalidRegistryException,
1242 MergeConflictException,
1243 CannotRegisterImplementationException, RuntimeException ) */
1245 static void doRevoke( const Reference < XSimpleRegistry >& xDest,
1246 const OUString& locationUrl );
1247 // throw( InvalidRegistryException, RuntimeException )
1248 Reference< XSimpleRegistry > getRegistryFromServiceManager();
1250 static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
1251 const Reference< XMultiComponentFactory > &rSMgr,
1252 const Reference < XComponentContext > & rCtx );
1254 private: // members
1255 Reference < XMultiComponentFactory > m_xSMgr;
1256 Reference < XComponentContext > m_xCtx;
1260 // ImplementationRegistration()
1262 ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
1263 : m_xSMgr( xCtx->getServiceManager() )
1264 , m_xCtx( xCtx )
1267 // XServiceInfo
1268 OUString ImplementationRegistration::getImplementationName()
1270 return OUString("com.sun.star.comp.stoc.ImplementationRegistration");
1273 // XServiceInfo
1274 sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName)
1276 return cppu::supportsService(this, ServiceName);
1279 // XServiceInfo
1280 Sequence< OUString > ImplementationRegistration::getSupportedServiceNames()
1282 Sequence< OUString > seqNames { "com.sun.star.registry.ImplementationRegistration" };
1283 return seqNames;
1286 Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
1288 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1289 Reference < XSimpleRegistry > xRegistry;
1291 if( xPropSet.is() ) {
1293 try { // the implementation does not support XIntrospectionAccess !
1295 Any aAny = xPropSet->getPropertyValue( spool().Registry );
1297 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1298 aAny >>= xRegistry;
1301 catch( UnknownPropertyException & ) {
1302 // empty reference is error signal !
1306 return xRegistry;
1310 // XInitialization
1312 void ImplementationRegistration::initialize(
1313 const css::uno::Sequence< css::uno::Any >& aArgs )
1316 if( aArgs.getLength() != 4 ) {
1317 throw IllegalArgumentException(
1318 "ImplementationRegistration::initialize() expects 4 parameters, got " + OUString::number( aArgs.getLength() ),
1319 Reference<XInterface > (), 0 );
1322 Reference< XImplementationLoader > rLoader;
1323 OUString loaderServiceName;
1324 OUString locationUrl;
1325 Reference< XSimpleRegistry > rReg;
1327 // 1st argument : An instance of an implementation loader
1328 if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1329 aArgs.getConstArray()[0] >>= rLoader;
1331 if( !rLoader.is()) {
1332 throw IllegalArgumentException(
1333 "ImplementationRegistration::initialize() invalid first parameter,"
1334 "expected " + cppu::UnoType<decltype(rLoader)>::get().getTypeName() +
1335 ", got " + aArgs.getConstArray()[0].getValueTypeName(),
1336 Reference< XInterface > (), 0 );
1339 // 2nd argument : The service name of the loader. This name is written into the registry
1340 if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
1341 aArgs.getConstArray()[1] >>= loaderServiceName;
1343 if( loaderServiceName.isEmpty() ) {
1344 throw IllegalArgumentException(
1345 "ImplementationRegistration::initialize() invalid second parameter,"
1346 "expected string, got " + aArgs.getConstArray()[1].getValueTypeName(),
1347 Reference< XInterface > (), 0 );
1350 // 3rd argument : The file name of the dll, that contains the loader
1351 if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
1352 aArgs.getConstArray()[2] >>= locationUrl;
1354 if( locationUrl.isEmpty() ) {
1355 throw IllegalArgumentException(
1356 "ImplementationRegistration::initialize() invalid third parameter,"
1357 "expected string, got " + aArgs.getConstArray()[2].getValueTypeName(),
1358 Reference< XInterface > (), 0 );
1361 // 4th argument : The registry, the service should be written to
1362 if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1363 aArgs.getConstArray()[3] >>= rReg;
1366 if( !rReg.is() ) {
1367 rReg = getRegistryFromServiceManager();
1368 if( !rReg.is() ) {
1369 throw IllegalArgumentException(
1370 "ImplementationRegistration::initialize() invalid fourth parameter,"
1371 "expected " + cppu::UnoType<decltype(rReg)>::get().getTypeName() +
1372 ", got " + aArgs.getConstArray()[3].getValueTypeName(),
1373 Reference< XInterface > (), 0 );
1377 doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
1381 // virtual function registerImplementationWithLocation of XImplementationRegistration2
1383 void ImplementationRegistration::registerImplementationWithLocation(
1384 const OUString& implementationLoaderUrl,
1385 const OUString& locationUrl,
1386 const OUString& registeredLocationUrl,
1387 const Reference < XSimpleRegistry > & xReg)
1389 prepareRegister(
1390 implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
1393 // helper function
1394 void ImplementationRegistration::prepareRegister(
1395 const OUString& implementationLoaderUrl,
1396 const OUString& locationUrl,
1397 const OUString& registeredLocationUrl,
1398 const Reference < XSimpleRegistry > & xReg)
1399 // throw( CannotRegisterImplementationException, RuntimeException )
1401 OUString activatorName;
1403 if (!implementationLoaderUrl.isEmpty())
1405 sal_Int32 nIndex = 0;
1406 activatorName = implementationLoaderUrl.getToken(0, ':', nIndex );
1407 } else
1409 // check locationUrl to find out what kind of loader is needed
1410 // set implLoaderUrl
1413 if( m_xSMgr.is() ) {
1416 Reference < XImplementationLoader > xAct(
1417 m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1418 if (xAct.is())
1420 Reference < XSimpleRegistry > xRegistry;
1422 if (xReg.is())
1424 // registry supplied by user
1425 xRegistry = xReg;
1427 else
1429 xRegistry = getRegistryFromServiceManager();
1432 if ( xRegistry.is())
1434 doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implementationLoaderUrl,
1435 locationUrl, registeredLocationUrl);
1438 else
1440 throw CannotRegisterImplementationException(
1441 "ImplementationRegistration::registerImplementation() - The service "
1442 + activatorName + " cannot be instantiated" );
1445 catch( CannotRegisterImplementationException & )
1447 throw;
1449 catch( const InvalidRegistryException & e )
1451 throw CannotRegisterImplementationException(
1452 "ImplementationRegistration::registerImplementation() "
1453 "InvalidRegistryException during registration (" + e.Message + ")" );
1455 catch( const MergeConflictException & e )
1457 throw CannotRegisterImplementationException(
1458 "ImplementationRegistration::registerImplementation() "
1459 "MergeConflictException during registration (" + e.Message + ")" );
1462 else
1464 throw CannotRegisterImplementationException(
1465 "ImplementationRegistration::registerImplementation() "
1466 "no componentcontext available to instantiate loader" );
1471 // virtual function registerImplementation of XImplementationRegistration
1473 void ImplementationRegistration::registerImplementation(
1474 const OUString& implementationLoaderUrl,
1475 const OUString& locationUrl,
1476 const Reference < XSimpleRegistry > & xReg)
1478 prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1482 // virtual function revokeImplementation of XImplementationRegistration
1484 sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
1485 const Reference < XSimpleRegistry >& xReg)
1487 bool ret = false;
1489 Reference < XSimpleRegistry > xRegistry;
1491 if (xReg.is()) {
1492 xRegistry = xReg;
1494 else {
1495 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1496 if( xPropSet.is() ) {
1497 try {
1498 Any aAny = xPropSet->getPropertyValue( spool().Registry );
1500 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
1502 aAny >>= xRegistry;
1505 catch ( UnknownPropertyException & ) {
1510 if (xRegistry.is())
1514 doRevoke(xRegistry, location);
1515 ret = true;
1517 catch( InvalidRegistryException & )
1519 // no way to transport the error, as no exception is specified and a runtime
1520 // exception is not appropriate.
1521 OSL_FAIL( "InvalidRegistryException during revokeImplementation" );
1525 return ret;
1529 // virtual function getImplementations of XImplementationRegistration
1531 Sequence< OUString > ImplementationRegistration::getImplementations(
1532 const OUString & implementationLoaderUrl,
1533 const OUString & locationUrl)
1535 OUString activatorName;
1537 if (!implementationLoaderUrl.isEmpty())
1539 sal_Int32 nIndex = 0;
1540 activatorName = implementationLoaderUrl.getToken(0, ':', nIndex );
1541 } else
1543 // check locationUrl to find out what kind of loader is needed
1544 // set implementationLoaderUrl
1547 if( m_xSMgr.is() ) {
1549 Reference < XImplementationLoader > xAct(
1550 m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1552 if (xAct.is())
1555 Reference < XSimpleRegistry > xReg =
1556 createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1558 if (xReg.is())
1562 xReg->open(OUString() /* in mem */, false, true);
1563 Reference < XRegistryKey > xImpl;
1565 { // only necessary for deleting the temporary variable of rootkey
1566 xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1568 if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1570 std::list <OUString> implNames;
1572 findImplementations(xImpl, implNames);
1574 if (!implNames.empty())
1576 Sequence<OUString> seqImpl(comphelper::containerToSequence(implNames));
1577 xImpl->closeKey();
1578 return seqImpl;
1582 xImpl->closeKey();
1584 catch(MergeConflictException&)
1587 catch(InvalidRegistryException&)
1594 return Sequence<OUString>();
1598 // virtual function checkInstantiation of XImplementationRegistration
1600 Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
1602 OSL_FAIL( "ImplementationRegistration::checkInstantiation not implemented" );
1603 return Sequence<OUString>();
1607 // helper function doRegistration
1610 void ImplementationRegistration::doRevoke(
1611 const Reference < XSimpleRegistry >& xDest,
1612 const OUString& locationUrl)
1613 // throw ( InvalidRegistryException, RuntimeException )
1615 if( xDest.is() )
1617 std::list<OUString> aNames;
1619 const StringPool &pool = spool();
1620 Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1622 Reference < XRegistryKey > xKey =
1623 xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
1624 if (xKey.is() && xKey->isValid())
1626 deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1629 xKey = xRootKey->openKey( pool.slash_SERVICES );
1630 if (xKey.is())
1632 std::list<OUString>::const_iterator iter = aNames.begin();
1634 while (iter != aNames.end())
1636 deleteAllServiceEntries(xDest, xKey, *iter);
1637 ++iter;
1641 xKey = xRootKey->openKey( "/SINGLETONS" );
1642 if (xKey.is() && xKey->isValid())
1644 delete_all_singleton_entries( xKey, aNames );
1647 if (xRootKey.is())
1648 xRootKey->closeKey();
1649 if (xKey.is() && xKey->isValid() )
1650 xKey->closeKey();
1654 void ImplementationRegistration::doRegister(
1655 const Reference< XMultiComponentFactory > & xSMgr,
1656 const Reference< XComponentContext > &xCtx,
1657 const Reference < XImplementationLoader > & xAct,
1658 const Reference < XSimpleRegistry >& xDest,
1659 const OUString& implementationLoaderUrl,
1660 const OUString& locationUrl,
1661 const OUString& registeredLocationUrl)
1662 /* throw ( InvalidRegistryException,
1663 MergeConflictException,
1664 CannotRegisterImplementationException, RuntimeException ) */
1666 Reference < XSimpleRegistry > xReg =
1667 createTemporarySimpleRegistry( xSMgr, xCtx );
1668 Reference < XRegistryKey > xSourceKey;
1670 if (xAct.is() && xReg.is() && xDest.is())
1674 xReg->open(OUString() /* in mem */, false, true);
1676 { // only necessary for deleting the temporary variable of rootkey
1677 xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1680 bool bSuccess =
1681 xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1682 if ( bSuccess )
1684 prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1686 xSourceKey->closeKey();
1688 xSourceKey = xReg->getRootKey();
1689 Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1690 stoc_impreg::mergeKeys( xDestKey, xSourceKey );
1691 xDestKey->closeKey();
1692 xSourceKey->closeKey();
1694 else
1696 throw CannotRegisterImplementationException(
1697 "ImplementationRegistration::doRegistration() component registration signaled failure" );
1700 // Cleanup Source registry.
1701 if ( xSourceKey->isValid() )
1702 xSourceKey->closeKey();
1704 catch(CannotRegisterImplementationException&)
1706 if ( xSourceKey->isValid() )
1707 xSourceKey->closeKey();
1708 // and throw again
1709 throw;
1715 Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1716 const Reference< XMultiComponentFactory > &rSMgr,
1717 const Reference < XComponentContext > & xCtx)
1720 Reference < XSimpleRegistry > xReg(
1721 rSMgr->createInstanceWithContext(
1722 spool().com_sun_star_registry_SimpleRegistry, xCtx ),
1723 UNO_QUERY);
1724 OSL_ASSERT( xReg.is() );
1725 return xReg;
1730 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1731 com_sun_star_comp_stoc_ImplementationRegistration_get_implementation(
1732 css::uno::XComponentContext *context,
1733 css::uno::Sequence<css::uno::Any> const &)
1735 return cppu::acquire(new ImplementationRegistration(context));
1738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */