update credits
[LibreOffice.git] / stoc / source / implementationregistration / implreg.cxx
blob7acd1494f717baac5a5d8dead4aba2f36dd37640
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 <boost/noncopyable.hpp>
25 #include <cppuhelper/queryinterface.hxx>
26 #include <cppuhelper/weak.hxx>
27 #include <cppuhelper/implbase3.hxx>
28 #include <cppuhelper/implementationentry.hxx>
29 #include <cppuhelper/supportsservice.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: private boost::noncopyable
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" )
96 const StringPool &spool()
98 static StringPool *pPool = 0;
99 if( ! pPool )
101 MutexGuard guard( Mutex::getGlobalMutex() );
102 if( ! pPool )
104 static StringPool pool;
105 pPool = &pool;
108 return *pPool;
112 // static deleteAllLinkReferences()
114 static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
115 const Reference < XRegistryKey >& xSource)
116 // throw ( InvalidRegistryException, RuntimeException )
118 Reference < XRegistryKey > xKey = xSource->openKey(
119 spool().slash_UNO_slash_REGISTRY_LINKS );
121 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
123 Sequence<OUString> linkNames = xKey->getAsciiListValue();
125 if (linkNames.getLength())
127 const OUString* pLinkNames = linkNames.getConstArray();
129 OUString aLinkName;
130 OUString aLinkParent;
131 Reference < XRegistryKey > xLinkParent;
132 const sal_Unicode* pTmpName = NULL;
133 const sal_Unicode* pShortName = NULL;
134 sal_Int32 sEnd = 0;
136 for (sal_Int32 i = 0; i < linkNames.getLength(); i++)
138 aLinkName = pLinkNames[i];
140 pTmpName = aLinkName.getStr();
142 if (pTmpName[0] != L'/')
143 continue;
145 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
146 if ( nIndex == -1 )
147 pShortName = 0;
148 else
149 pShortName = pTmpName+nIndex;
151 while (pShortName && pShortName[1] == L'%')
153 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
154 if ( nIndex == -1 )
155 pShortName = 0;
156 else
157 pShortName += nIndex+2;
160 if (pShortName)
162 aLinkName = aLinkName.copy(0, pShortName - pTmpName);
165 xReg->getRootKey()->deleteLink(aLinkName);
167 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
169 aLinkParent = aLinkName.copy(0, sEnd);
171 while(!aLinkParent.isEmpty())
173 xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
175 if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0))
177 aLinkName = aLinkParent;
179 xReg->getRootKey()->deleteKey(aLinkParent);
181 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
183 aLinkParent = aLinkName.copy(0, sEnd);
184 } else
186 break;
195 // static prepareLink
197 static void prepareLink( const Reference < XSimpleRegistry > & xDest,
198 const Reference < XRegistryKey > & xSource,
199 const OUString& link)
200 // throw ( InvalidRegistryException, RuntimeException )
202 OUString linkRefName = xSource->getKeyName();
203 OUString linkName(link);
204 bool isRelativ = false;
206 const sal_Unicode* pTmpName = link.getStr();
207 const sal_Unicode* pShortName;
208 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
209 if ( nIndex == -1 )
210 pShortName = 0;
211 else
212 pShortName = pTmpName+nIndex;
214 if (pTmpName[0] != L'/')
215 isRelativ = true;
217 while (pShortName && pShortName[1] == L'%')
219 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
220 if ( nIndex == -1 )
221 pShortName = 0;
222 else
223 pShortName += nIndex+2;
226 if (pShortName)
228 linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1);
229 linkName = link.copy(0, pShortName - pTmpName);
232 if (isRelativ)
233 xSource->createLink(linkName, linkRefName);
234 else
235 xDest->getRootKey()->createLink(linkName, linkRefName);
239 // static searchImplForLink
241 static OUString searchImplForLink(
242 const Reference < XRegistryKey > & xRootKey,
243 const OUString& linkName,
244 const OUString& implName )
245 // throw ( InvalidRegistryException, RuntimeException )
247 const StringPool & pool = spool();
248 Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
249 if (xKey.is())
251 Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
252 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
253 OUString key_name( pool.slash_UNO + linkName );
255 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
259 Reference < XRegistryKey > xImplKey( pSubKeys[i] );
260 if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
262 OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
263 if (implName != oldImplName)
265 return oldImplName;
269 catch(InvalidRegistryException&)
275 return OUString();
279 // static searchLinkTargetForImpl
281 static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
282 const OUString& linkName,
283 const OUString& implName)
284 // throw ( InvalidRegistryException, RuntimeException )
286 OUString ret;
288 // try
289 // {
290 const StringPool & pool = spool();
291 Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
293 if (xKey.is())
295 Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
297 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
298 Reference < XRegistryKey > xImplKey;
300 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
302 xImplKey = pSubKeys[i];
304 OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
305 OUString qualifiedLinkName( pool.slash_UNO );
306 qualifiedLinkName += linkName;
307 if (tmpImplName == implName &&
308 xImplKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK)
310 return xImplKey->getLinkTarget( qualifiedLinkName );
314 // }
315 // catch(InvalidRegistryException&)
316 // {
317 // }
319 return ret;
323 // static createUniqueSubEntry
325 static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
326 const OUString& value)
327 // throw ( InvalidRegistryException, RuntimeException )
329 if (xSuperKey.is())
331 // try
332 // {
333 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
335 sal_Int32 length = 0;
336 bool bReady = false;
338 Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
339 length = implEntries.getLength();
341 for (sal_Int32 i = 0; !bReady && (i < length); i++)
343 bReady = (implEntries.getConstArray()[i] == value);
346 if (bReady)
348 Sequence<OUString> implEntriesNew(length);
349 implEntriesNew.getArray()[0] = value;
351 for (sal_Int32 i=0, j=1; i < length; i++)
353 if (implEntries.getConstArray()[i] != value)
354 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
356 xSuperKey->setAsciiListValue(implEntriesNew);
357 } else
359 Sequence<OUString> implEntriesNew(length+1);
360 implEntriesNew.getArray()[0] = value;
362 for (sal_Int32 i = 0; i < length; i++)
364 implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i];
366 xSuperKey->setAsciiListValue(implEntriesNew);
368 } else
370 Sequence<OUString> implEntriesNew(1);
372 implEntriesNew.getArray()[0] = value;
374 xSuperKey->setAsciiListValue(implEntriesNew);
376 // }
377 // catch(InvalidRegistryException&)
378 // {
379 // }
384 // static deleteSubEntry
386 static 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 static 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 static 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 tmpPath(path);
471 OUString newPath = tmpPath.copy(0, tmpPath.lastIndexOf('/'));
473 if (newPath.getLength() > 1)
474 deletePathIfPossible(xRootKey, newPath);
477 catch(InvalidRegistryException&)
484 // static deleteUserLink
486 static void deleteUserLink(const Reference < XRegistryKey >& xRootKey,
487 const OUString& linkName,
488 const OUString& linkTarget,
489 const OUString& implName)
490 // throw ( InvalidRegistryException, RuntimeException )
492 bool bClean = false;
494 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
496 OUString tmpTarget = xRootKey->getLinkTarget(linkName);
498 if (tmpTarget == linkTarget)
500 xRootKey->deleteLink(linkName);
504 Reference < XRegistryKey > xOldKey = xRootKey->openKey(
505 linkName + spool().colon_old );
506 if (xOldKey.is())
508 if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
510 Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
511 sal_Int32 length = implEntries.getLength();
512 sal_Int32 equals = 0;
513 bool hasNoImplementations = false;
515 for (sal_Int32 i = 0; i < length; i++)
517 if (implEntries.getConstArray()[i] == implName)
518 equals++;
521 if (equals == length)
523 hasNoImplementations = true;
524 } else
526 OUString oldImpl;
528 if (length > equals + 1)
530 Sequence<OUString> implEntriesNew(length - equals - 1);
532 sal_Int32 j = 0;
533 bool first = true;
534 for (sal_Int32 i = 0; i < length; i++)
536 if (implEntries.getConstArray()[i] != implName)
538 if (first)
540 oldImpl = implEntries.getConstArray()[i];
541 first = false;
542 } else
544 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
549 xOldKey->setAsciiListValue(implEntriesNew);
550 } else
552 oldImpl = implEntries.getConstArray()[0];
553 OUString path(xOldKey->getKeyName());
554 xOldKey->closeKey();
555 xRootKey->deleteKey(path);
558 OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
559 if (!oldTarget.isEmpty())
561 xRootKey->createLink(linkName, oldTarget);
565 if (hasNoImplementations)
567 bClean = true;
568 hasNoImplementations = false;
569 OUString path(xOldKey->getKeyName());
570 xOldKey->closeKey();
571 xRootKey->deleteKey(path);
574 } else
576 bClean = true;
579 if (bClean)
581 OUString tmpName(linkName);
582 OUString path = tmpName.copy(0, tmpName.lastIndexOf('/'));
583 deletePathIfPossible(xRootKey, path);
588 // static prepareUserKeys
590 static void prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
591 const Reference < XRegistryKey >& xUnoKey,
592 const Reference < XRegistryKey >& xKey,
593 const OUString& implName,
594 bool bRegister)
596 bool hasSubKeys = false;
598 Sequence<OUString> keyNames = xKey->getKeyNames();
600 OUString relativKey;
601 if (keyNames.getLength())
602 relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
604 if (keyNames.getLength() == 1 &&
605 xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
607 hasSubKeys = true;
609 OUString linkTarget = xKey->getLinkTarget(relativKey);
610 OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
612 linkName = linkName + "/" + relativKey;
614 if (bRegister)
616 prepareUserLink(xDest, linkName, linkTarget, implName);
617 } else
619 deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
621 } else
623 Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
625 if (subKeys.getLength())
627 hasSubKeys = true;
628 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
630 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
632 prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
637 if (! hasSubKeys)
639 OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
641 Reference < XRegistryKey > xRootKey = xDest->getRootKey();
642 if (bRegister)
644 createUniqueSubEntry(xRootKey->createKey(keyName), implName);
646 else
648 Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
649 if( rKey.is() )
651 deleteSubEntry(rKey, implName);
652 xRootKey->deleteKey(keyName);
655 OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
656 if( !path.isEmpty() )
658 deletePathIfPossible(xRootKey, path);
665 // static deleteAllImplementations
667 static void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg,
668 const Reference < XRegistryKey >& xSource,
669 const OUString& locationUrl,
670 std::list<OUString> & implNames)
671 // throw (InvalidRegistryException, RuntimeException)
673 Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
675 if (subKeys.getLength() > 0)
677 const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
678 Reference < XRegistryKey > xImplKey;
679 bool hasLocationUrl = false;
681 const StringPool &pool = spool();
682 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
684 xImplKey = pSubKeys[i];
685 Reference < XRegistryKey > xKey = xImplKey->openKey(
686 pool.slash_UNO_slash_LOCATION );
688 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
690 if (xKey->getAsciiValue() == locationUrl)
692 hasLocationUrl = true;
694 OUString implName(xImplKey->getKeyName().getStr() + 1);
695 sal_Int32 firstDot = implName.indexOf('/');
697 if (firstDot >= 0)
698 implName = implName.copy(firstDot + 1);
700 implNames.push_back(implName);
702 deleteAllLinkReferences(xReg, xImplKey);
704 xKey = xImplKey->openKey( pool.slash_UNO );
705 if (xKey.is())
707 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
709 if (subKeys2.getLength())
711 const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
713 for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
715 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
716 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
717 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
718 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
719 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
721 prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, false);
729 if (hasLocationUrl)
731 hasLocationUrl = false;
732 OUString path(xImplKey->getKeyName());
733 xImplKey->closeKey();
734 xReg->getRootKey()->deleteKey(path);
738 subKeys = xSource->openKeys();
739 if (subKeys.getLength() == 0)
741 OUString path(xSource->getKeyName());
742 xSource->closeKey();
743 xReg->getRootKey()->deleteKey(path);
745 } else
747 OUString path(xSource->getKeyName());
748 xSource->closeKey();
749 xReg->getRootKey()->deleteKey(path);
754 static void delete_all_singleton_entries(
755 Reference < registry::XRegistryKey > const & xSingletons_section,
756 ::std::list< OUString > const & impl_names )
757 // throw (InvalidRegistryException, RuntimeException)
759 Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
760 Reference< registry::XRegistryKey > const * subkeys = singletons.getConstArray();
761 for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
763 Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
764 Reference< registry::XRegistryKey > xRegisteredImplNames(
765 xSingleton->openKey( "REGISTERED_BY" ) );
766 if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
768 Sequence< OUString > registered_implnames;
771 registered_implnames = xRegisteredImplNames->getAsciiListValue();
773 catch (registry::InvalidValueException &)
776 OUString const * p = registered_implnames.getConstArray();
777 sal_Int32 nOrigRegLength = registered_implnames.getLength();
778 sal_Int32 nNewLength = nOrigRegLength;
779 for ( sal_Int32 n = nOrigRegLength; n--; )
781 OUString const & registered_implname = p[ n ];
783 ::std::list< OUString >::const_iterator iPos( impl_names.begin() );
784 ::std::list< OUString >::const_iterator const iEnd( impl_names.end() );
785 for ( ; iPos != iEnd; ++iPos )
787 if (iPos->equals( registered_implname ))
789 registered_implnames[ n ] = p[ nNewLength -1 ];
790 --nNewLength;
795 if (nNewLength != nOrigRegLength)
797 if (0 == nNewLength)
799 // remove whole entry
800 xRegisteredImplNames->closeKey();
801 xSingleton->deleteKey( "REGISTERED_BY" );
802 // registry key cannot provide its relative name, only absolute :(
803 OUString abs( xSingleton->getKeyName() );
804 xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
806 else
808 registered_implnames.realloc( nNewLength );
809 xRegisteredImplNames->setAsciiListValue( registered_implnames );
817 // static deleteAllServiceEntries
819 static void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg,
820 const Reference < XRegistryKey >& xSource,
821 const OUString& implName)
822 // throw ( InvalidRegistryException, RuntimeException )
824 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
826 if (subKeys.getLength() > 0)
828 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
829 Reference < XRegistryKey > xServiceKey;
830 bool hasNoImplementations = false;
832 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
834 xServiceKey = pSubKeys[i];
836 if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
838 Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
839 sal_Int32 length = implEntries.getLength();
840 sal_Int32 equals = 0;
842 for (sal_Int32 j = 0; j < length; j++)
844 if (implEntries.getConstArray()[j] == implName)
845 equals++;
848 if (equals == length)
850 hasNoImplementations = true;
851 } else
853 if (equals > 0)
855 Sequence<OUString> implEntriesNew(length-equals);
857 sal_Int32 j = 0;
858 for (sal_Int32 k = 0; k < length; k++)
860 if (implEntries.getConstArray()[k] != implName)
862 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[k];
866 xServiceKey->setAsciiListValue(implEntriesNew);
871 if (hasNoImplementations)
873 hasNoImplementations = false;
874 OUString path(xServiceKey->getKeyName());
875 xServiceKey->closeKey();
876 xReg->getRootKey()->deleteKey(path);
880 subKeys = xSource->openKeys();
881 if (subKeys.getLength() == 0)
883 OUString path(xSource->getKeyName());
884 xSource->closeKey();
885 xReg->getRootKey()->deleteKey(path);
887 } else
889 OUString path(xSource->getKeyName());
890 xSource->closeKey();
891 xReg->getRootKey()->deleteKey(path);
896 static bool is_supported_service(
897 OUString const & service_name,
898 Reference< reflection::XServiceTypeDescription > const & xService_td )
900 if (xService_td->getName().equals( service_name ))
901 return true;
902 Sequence< Reference< reflection::XServiceTypeDescription > > seq(
903 xService_td->getMandatoryServices() );
904 Reference< reflection::XServiceTypeDescription > const * p = seq.getConstArray();
905 for ( sal_Int32 nPos = seq.getLength(); nPos--; )
907 if (is_supported_service( service_name, p[ nPos ] ))
908 return true;
910 return false;
914 static void insert_singletons(
915 Reference< registry::XSimpleRegistry > const & xDest,
916 Reference< registry::XRegistryKey > const & xImplKey,
917 Reference< XComponentContext > const & xContext )
918 // throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
920 // singletons
921 Reference< registry::XRegistryKey > xKey( xImplKey->openKey( "UNO/SINGLETONS" ) );
922 if (xKey.is() && xKey->isValid())
924 OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
925 // singleton entries
926 Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
927 Reference< registry::XRegistryKey > const * p = xSingletons_section.getConstArray();
928 for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
930 Reference< registry::XRegistryKey > const & xSingleton = p[ nPos ];
931 OUString singleton_name(
932 xSingleton->getKeyName().copy(
933 implname.getLength() + sizeof ("/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
934 OUString service_name( xSingleton->getStringValue() );
936 OUString keyname( "/SINGLETONS/" + singleton_name );
937 Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
938 if (xKey2.is() && xKey2->isValid())
942 OUString existing_name( xKey2->getStringValue() );
943 if (! existing_name.equals( service_name ))
945 Reference< container::XHierarchicalNameAccess > xTDMgr;
946 OUString the_tdmgr =
947 "/singletons/com.sun.star.reflection.theTypeDescriptionManager";
948 xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
949 if (! xTDMgr.is())
951 throw RuntimeException( "cannot get singleton " + the_tdmgr );
955 Reference< reflection::XServiceTypeDescription > xExistingService_td;
956 xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
957 if (! xExistingService_td.is())
959 throw RuntimeException( "cannot get service type description: " + existing_name );
962 // everything's fine if existing service entry supports the one
963 // to be registered
964 if (! is_supported_service( service_name, xExistingService_td ))
966 OUStringBuffer buf( 64 );
967 buf.append( "existing singleton service (" );
968 buf.append( singleton_name );
969 buf.append( '=' );
970 buf.append( existing_name );
971 buf.append( ") does not support given one: " );
972 buf.append( service_name );
973 throw registry::CannotRegisterImplementationException(
974 buf.makeStringAndClear() );
977 catch (const container::NoSuchElementException & exc)
979 throw RuntimeException(
980 "cannot get service type description: " + exc.Message );
984 catch (registry::InvalidValueException &)
986 // repair
987 xKey2->setStringValue( service_name );
990 else
992 // insert singleton entry
993 xKey2 = xDest->getRootKey()->createKey( keyname );
994 xKey2->setStringValue( service_name );
997 Reference< registry::XRegistryKey > xRegisteredImplNames(
998 xKey2->openKey( "REGISTERED_BY" ) );
999 if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
1001 // create
1002 xRegisteredImplNames = xKey2->createKey( "REGISTERED_BY" );
1005 Sequence< OUString > implnames;
1008 implnames = xRegisteredImplNames->getAsciiListValue();
1010 catch (registry::InvalidValueException &)
1013 // check implname is already in
1014 sal_Int32 nPos_implnames = implnames.getLength();
1015 OUString const * pImplnames = implnames.getConstArray();
1016 while (nPos_implnames--)
1018 if (implname.equals( pImplnames[ nPos_implnames ] ))
1019 break;
1021 if (nPos_implnames < 0)
1023 // append and write back
1024 implnames.realloc( implnames.getLength() +1 );
1025 implnames[ implnames.getLength() -1 ] = implname;
1026 xRegisteredImplNames->setAsciiListValue( implnames );
1034 // static prepareRegistry
1036 static void prepareRegistry(
1037 const Reference < XSimpleRegistry >& xDest,
1038 const Reference < XRegistryKey >& xSource,
1039 const OUString& implementationLoaderUrl,
1040 const OUString& locationUrl,
1041 Reference< XComponentContext > const & xContext )
1042 // throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
1044 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1046 if (!subKeys.getLength())
1048 throw InvalidRegistryException(
1049 "prepareRegistry(): source registry is empty" );
1052 const StringPool & pool = spool();
1054 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1055 Reference < XRegistryKey > xImplKey;
1057 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1059 xImplKey = pSubKeys[i];
1061 Reference < XRegistryKey > xKey = xImplKey->openKey(
1062 pool.slash_UNO_slash_SERVICES );
1064 if (xKey.is())
1066 // update entries in SERVICES section
1067 Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
1068 const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
1070 OUString implName = OUString(xImplKey->getKeyName().getStr() + 1);
1071 sal_Int32 firstDot = implName.indexOf('/');
1073 if (firstDot >= 0)
1074 implName = implName.copy(firstDot + 1);
1076 sal_Int32 offset = xKey->getKeyName().getLength() + 1;
1078 for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
1080 OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
1082 createUniqueSubEntry(
1083 xDest->getRootKey()->createKey(
1084 pool.slash_SERVICES + serviceName ),
1085 implName);
1088 xKey = xImplKey->openKey( pool.slash_UNO );
1089 if (xKey.is())
1091 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
1093 if (subKeys2.getLength())
1095 const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
1097 for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
1099 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
1100 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
1101 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
1103 prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, true);
1110 // update LOCATION entry
1111 xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
1113 if (xKey.is())
1115 xKey->setAsciiValue(locationUrl);
1118 // update ACTIVATOR entry
1119 xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
1121 if (xKey.is())
1123 xKey->setAsciiValue(implementationLoaderUrl);
1126 xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
1128 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
1130 // update link entries in REGISTRY_LINKS section
1131 Sequence<OUString> linkNames = xKey->getAsciiListValue();
1133 if (linkNames.getLength())
1135 const OUString* pLinkNames = linkNames.getConstArray();
1137 for (sal_Int32 j = 0; j < linkNames.getLength(); j++)
1139 prepareLink(xDest, xImplKey, pLinkNames[j]);
1144 insert_singletons( xDest, xImplKey, xContext );
1149 static void findImplementations( const Reference < XRegistryKey > & xSource,
1150 std::list <OUString>& implNames)
1152 bool isImplKey = false;
1156 Reference < XRegistryKey > xKey = xSource->openKey(
1157 spool().slash_UNO_slash_SERVICES );
1159 if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
1161 isImplKey = true;
1163 OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace('/', '.').getStr();
1164 sal_Int32 firstDot = implName.indexOf('.');
1166 if (firstDot >= 0)
1167 implName = implName.copy(firstDot + 1);
1169 implNames.push_back(implName);
1172 catch(InvalidRegistryException&)
1176 if (isImplKey) return;
1180 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1182 if (subKeys.getLength() > 0)
1184 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1186 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1188 findImplementations(pSubKeys[i], implNames);
1193 catch(InvalidRegistryException&)
1199 class ImplementationRegistration
1200 : public WeakImplHelper3< XImplementationRegistration2, XServiceInfo, XInitialization >
1202 public:
1203 ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
1204 virtual ~ImplementationRegistration();
1206 // XServiceInfo
1207 OUString SAL_CALL getImplementationName() throw(RuntimeException, std::exception) SAL_OVERRIDE;
1208 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException, std::exception) SAL_OVERRIDE;
1209 Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException, std::exception) SAL_OVERRIDE;
1211 // XImplementationRegistration
1212 virtual void SAL_CALL registerImplementation(
1213 const OUString& implementationLoader,
1214 const OUString& location,
1215 const Reference < XSimpleRegistry > & xReg)
1216 throw( CannotRegisterImplementationException, RuntimeException, std::exception ) SAL_OVERRIDE;
1218 virtual sal_Bool SAL_CALL revokeImplementation(
1219 const OUString& location,
1220 const Reference < XSimpleRegistry >& xReg)
1221 throw( RuntimeException, std::exception ) SAL_OVERRIDE;
1223 virtual Sequence< OUString > SAL_CALL getImplementations(
1224 const OUString& implementationLoader,
1225 const OUString& location)
1226 throw( RuntimeException, std::exception ) SAL_OVERRIDE;
1227 virtual Sequence< OUString > SAL_CALL checkInstantiation(
1228 const OUString& implementationName)
1229 throw( RuntimeException, std::exception ) SAL_OVERRIDE;
1231 // XImplementationRegistration2
1232 virtual void SAL_CALL registerImplementationWithLocation(
1233 const OUString& implementationLoader,
1234 const OUString& location,
1235 const OUString& registeredLocation,
1236 const Reference < XSimpleRegistry > & xReg)
1237 throw( CannotRegisterImplementationException, RuntimeException, std::exception ) SAL_OVERRIDE;
1239 // XInitialization
1240 virtual void SAL_CALL initialize(
1241 const css::uno::Sequence< css::uno::Any >& aArguments )
1242 throw( css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1244 private: // helper methods
1245 void prepareRegister(
1246 const OUString& implementationLoader,
1247 const OUString& location,
1248 const OUString& registeredLocation,
1249 const Reference < XSimpleRegistry > & xReg);
1250 // throw( CannotRegisterImplementationException, RuntimeException )
1252 static void doRegister( const Reference < XMultiComponentFactory >& xSMgr,
1253 const Reference < XComponentContext > &xCtx,
1254 const Reference < XImplementationLoader >& xAct,
1255 const Reference < XSimpleRegistry >& xDest,
1256 const OUString& implementationLoaderUrl,
1257 const OUString& locationUrl,
1258 const OUString& registeredLocationUrl);
1259 /* throw ( InvalidRegistryException,
1260 MergeConflictException,
1261 CannotRegisterImplementationException, RuntimeException ) */
1263 static void doRevoke( const Reference < XSimpleRegistry >& xDest,
1264 const OUString& locationUrl );
1265 // throw( InvalidRegistryException, RuntimeException )
1266 Reference< XSimpleRegistry > getRegistryFromServiceManager();
1268 static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
1269 const Reference< XMultiComponentFactory > &rSMgr,
1270 const Reference < XComponentContext > & rCtx );
1272 private: // members
1273 Reference < XMultiComponentFactory > m_xSMgr;
1274 Reference < XComponentContext > m_xCtx;
1278 // ImplementationRegistration()
1280 ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
1281 : m_xSMgr( xCtx->getServiceManager() )
1282 , m_xCtx( xCtx )
1286 // ~ImplementationRegistration()
1288 ImplementationRegistration::~ImplementationRegistration() {}
1290 // XServiceInfo
1291 OUString ImplementationRegistration::getImplementationName() throw(RuntimeException, std::exception)
1293 return OUString("com.sun.star.comp.stoc.ImplementationRegistration");
1296 // XServiceInfo
1297 sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw(RuntimeException, std::exception)
1299 return cppu::supportsService(this, ServiceName);
1302 // XServiceInfo
1303 Sequence< OUString > ImplementationRegistration::getSupportedServiceNames() throw(RuntimeException, std::exception)
1305 Sequence< OUString > seqNames(1);
1306 seqNames[0] = "com.sun.star.registry.ImplementationRegistration";
1307 return seqNames;
1310 Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
1312 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1313 Reference < XSimpleRegistry > xRegistry;
1315 if( xPropSet.is() ) {
1317 try { // the implementation does not support XIntrospectionAccess !
1319 Any aAny = xPropSet->getPropertyValue( spool().Registry );
1321 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1322 aAny >>= xRegistry;
1325 catch( UnknownPropertyException & ) {
1326 // empty reference is error signal !
1330 return xRegistry;
1335 // XInitialization
1337 void ImplementationRegistration::initialize(
1338 const css::uno::Sequence< css::uno::Any >& aArgs )
1339 throw( css::uno::Exception, css::uno::RuntimeException, std::exception)
1342 if( aArgs.getLength() != 4 ) {
1343 OUStringBuffer buf;
1344 buf.append( "ImplementationRegistration::initialize() expects 4 parameters, got " );
1345 buf.append( (sal_Int32) aArgs.getLength() );
1346 throw IllegalArgumentException( buf.makeStringAndClear(),
1347 Reference<XInterface > (),
1348 0 );
1351 Reference< XImplementationLoader > rLoader;
1352 OUString loaderServiceName;
1353 OUString locationUrl;
1354 Reference< XSimpleRegistry > rReg;
1356 // 1st argument : An instance of an implementation loader
1357 if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1358 aArgs.getConstArray()[0] >>= rLoader;
1360 if( !rLoader.is()) {
1361 OUStringBuffer buf;
1362 buf.append( "ImplementationRegistration::initialize() invalid first parameter,"
1363 "expected " );
1364 buf.append( cppu::UnoType<decltype(rLoader)>::get().getTypeName() );
1365 buf.append( ", got " );
1366 buf.append( aArgs.getConstArray()[0].getValueTypeName() );
1367 throw IllegalArgumentException( buf.makeStringAndClear(),
1368 Reference< XInterface > (),
1369 0 );
1372 // 2nd argument : The service name of the loader. This name is written into the registry
1373 if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
1374 aArgs.getConstArray()[1] >>= loaderServiceName;
1376 if( loaderServiceName.isEmpty() ) {
1377 OUStringBuffer buf;
1378 buf.append( "ImplementationRegistration::initialize() invalid second parameter,"
1379 "expected string, got " );
1380 buf.append( aArgs.getConstArray()[1].getValueTypeName() );
1381 throw IllegalArgumentException( buf.makeStringAndClear(),
1382 Reference< XInterface > (),
1383 0 );
1386 // 3rd argument : The file name of the dll, that contains the loader
1387 if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
1388 aArgs.getConstArray()[2] >>= locationUrl;
1390 if( locationUrl.isEmpty() ) {
1391 OUStringBuffer buf;
1392 buf.append( "ImplementationRegistration::initialize() invalid third parameter,"
1393 "expected string, got " );
1394 buf.append( aArgs.getConstArray()[2].getValueTypeName() );
1395 throw IllegalArgumentException( buf.makeStringAndClear(),
1396 Reference< XInterface > (),
1397 0 );
1400 // 4th argument : The registry, the service should be written to
1401 if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1402 aArgs.getConstArray()[3] >>= rReg;
1405 if( !rReg.is() ) {
1406 rReg = getRegistryFromServiceManager();
1407 if( !rReg.is() ) {
1408 OUStringBuffer buf;
1409 buf.append( "ImplementationRegistration::initialize() invalid fourth parameter,"
1410 "expected " );
1411 buf.append( cppu::UnoType<decltype(rReg)>::get().getTypeName() );
1412 buf.append( ", got " );
1413 buf.append( aArgs.getConstArray()[3].getValueTypeName() );
1414 throw IllegalArgumentException( buf.makeStringAndClear(),
1415 Reference< XInterface > (),
1416 0 );
1420 doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
1426 // virtual function registerImplementationWithLocation of XImplementationRegistration2
1428 void ImplementationRegistration::registerImplementationWithLocation(
1429 const OUString& implementationLoaderUrl,
1430 const OUString& locationUrl,
1431 const OUString& registeredLocationUrl,
1432 const Reference < XSimpleRegistry > & xReg)
1433 throw( CannotRegisterImplementationException, RuntimeException, std::exception )
1435 prepareRegister(
1436 implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
1439 // helper function
1440 void ImplementationRegistration::prepareRegister(
1441 const OUString& implementationLoaderUrl,
1442 const OUString& locationUrl,
1443 const OUString& registeredLocationUrl,
1444 const Reference < XSimpleRegistry > & xReg)
1445 // throw( CannotRegisterImplementationException, RuntimeException )
1447 OUString implLoaderUrl(implementationLoaderUrl);
1448 OUString activatorName;
1450 if (!implementationLoaderUrl.isEmpty())
1452 OUString tmpActivator(implementationLoaderUrl);
1453 sal_Int32 nIndex = 0;
1454 activatorName = tmpActivator.getToken(0, ':', nIndex );
1455 } else
1457 // check locationUrl to find out what kind of loader is needed
1458 // set iimplLoaderUrl
1461 if( m_xSMgr.is() ) {
1464 Reference < XImplementationLoader > xAct(
1465 m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1466 if (xAct.is())
1468 Reference < XSimpleRegistry > xRegistry;
1470 if (xReg.is())
1472 // registry supplied by user
1473 xRegistry = xReg;
1475 else
1477 xRegistry = getRegistryFromServiceManager();
1480 if ( xRegistry.is())
1482 doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implLoaderUrl,
1483 locationUrl, registeredLocationUrl);
1486 else
1488 OUStringBuffer buf( 128 );
1489 buf.appendAscii( "ImplementationRegistration::registerImplementation() - The service " );
1490 buf.append( activatorName );
1491 buf.appendAscii( " cannot be instantiated\n" );
1492 throw CannotRegisterImplementationException(
1493 buf.makeStringAndClear() );
1496 catch( CannotRegisterImplementationException & )
1498 throw;
1500 catch( const InvalidRegistryException & e )
1502 OUStringBuffer buf;
1503 buf.append( "ImplementationRegistration::registerImplementation() "
1504 "InvalidRegistryException during registration (" );
1505 buf.append( e.Message );
1506 buf.append( ")" );
1507 throw CannotRegisterImplementationException(
1508 buf.makeStringAndClear() );
1510 catch( const MergeConflictException & e )
1512 OUStringBuffer buf;
1513 buf.append( "ImplementationRegistration::registerImplementation() "
1514 "MergeConflictException during registration (" );
1515 buf.append( e.Message );
1516 buf.append( ")" );
1517 throw CannotRegisterImplementationException(
1518 buf.makeStringAndClear() );
1521 else
1523 throw CannotRegisterImplementationException(
1524 "ImplementationRegistration::registerImplementation() "
1525 "no componentcontext available to instantiate loader" );
1530 // virtual function registerImplementation of XImplementationRegistration
1532 void ImplementationRegistration::registerImplementation(
1533 const OUString& implementationLoaderUrl,
1534 const OUString& locationUrl,
1535 const Reference < XSimpleRegistry > & xReg)
1536 throw( CannotRegisterImplementationException, RuntimeException, std::exception )
1538 prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1543 // virtual function revokeImplementation of XImplementationRegistration
1545 sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
1546 const Reference < XSimpleRegistry >& xReg)
1547 throw ( RuntimeException, std::exception )
1549 bool ret = false;
1551 Reference < XSimpleRegistry > xRegistry;
1553 if (xReg.is()) {
1554 xRegistry = xReg;
1556 else {
1557 Reference < XPropertySet > xPropSet = Reference< XPropertySet >::query( m_xSMgr );
1558 if( xPropSet.is() ) {
1559 try {
1560 Any aAny = xPropSet->getPropertyValue( spool().Registry );
1562 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
1564 aAny >>= xRegistry;
1567 catch ( UnknownPropertyException & ) {
1572 if (xRegistry.is())
1576 doRevoke(xRegistry, location);
1577 ret = true;
1579 catch( InvalidRegistryException & )
1581 // no way to transport the error, as no exception is specified and a runtime
1582 // exception is not appropriate.
1583 OSL_FAIL( "InvalidRegistryException during revokeImplementation" );
1587 return ret;
1591 // virtual function getImplementations of XImplementationRegistration
1593 Sequence< OUString > ImplementationRegistration::getImplementations(
1594 const OUString & implementationLoaderUrl,
1595 const OUString & locationUrl)
1596 throw ( RuntimeException, std::exception )
1598 OUString activatorName;
1600 if (!implementationLoaderUrl.isEmpty())
1602 OUString tmpActivator(implementationLoaderUrl);
1603 sal_Int32 nIndex = 0;
1604 activatorName = tmpActivator.getToken(0, ':', nIndex );
1605 } else
1607 // check locationUrl to find out what kind of loader is needed
1608 // set implementationLoaderUrl
1611 if( m_xSMgr.is() ) {
1613 Reference < XImplementationLoader > xAct(
1614 m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1616 if (xAct.is())
1619 Reference < XSimpleRegistry > xReg =
1620 createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1622 if (xReg.is())
1626 xReg->open(OUString() /* in mem */, sal_False, sal_True);
1627 Reference < XRegistryKey > xImpl;
1629 { // only necessary for deleting the temporary variable of rootkey
1630 xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1632 if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1634 std::list <OUString> implNames;
1636 findImplementations(xImpl, implNames);
1638 if (!implNames.empty())
1640 std::list<OUString>::const_iterator iter = implNames.begin();
1642 Sequence<OUString> seqImpl(implNames.size());
1643 OUString *pImplNames = seqImpl.getArray();
1645 sal_Int32 index = 0;
1646 while (iter != implNames.end())
1648 pImplNames[index] = *iter;
1649 index++;
1650 ++iter;
1653 xImpl->closeKey();
1654 return seqImpl;
1658 xImpl->closeKey();
1660 catch(MergeConflictException&)
1663 catch(InvalidRegistryException&)
1670 return Sequence<OUString>();
1674 // virtual function checkInstantiation of XImplementationRegistration
1676 Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
1677 throw ( RuntimeException, std::exception )
1679 OSL_FAIL( "ImplementationRegistration::checkInstantiation not implemented" );
1680 return Sequence<OUString>();
1684 // helper function doRegistration
1687 void ImplementationRegistration::doRevoke(
1688 const Reference < XSimpleRegistry >& xDest,
1689 const OUString& locationUrl)
1690 // throw ( InvalidRegistryException, RuntimeException )
1692 if( xDest.is() )
1694 std::list<OUString> aNames;
1696 const StringPool &pool = spool();
1697 Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1699 Reference < XRegistryKey > xKey =
1700 xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
1701 if (xKey.is() && xKey->isValid())
1703 deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1706 xKey = xRootKey->openKey( pool.slash_SERVICES );
1707 if (xKey.is())
1709 std::list<OUString>::const_iterator iter = aNames.begin();
1711 while (iter != aNames.end())
1713 deleteAllServiceEntries(xDest, xKey, *iter);
1714 ++iter;
1718 xKey = xRootKey->openKey( "/SINGLETONS" );
1719 if (xKey.is() && xKey->isValid())
1721 delete_all_singleton_entries( xKey, aNames );
1724 if (xRootKey.is())
1725 xRootKey->closeKey();
1726 if (xKey.is() && xKey->isValid() )
1727 xKey->closeKey();
1731 void ImplementationRegistration::doRegister(
1732 const Reference< XMultiComponentFactory > & xSMgr,
1733 const Reference< XComponentContext > &xCtx,
1734 const Reference < XImplementationLoader > & xAct,
1735 const Reference < XSimpleRegistry >& xDest,
1736 const OUString& implementationLoaderUrl,
1737 const OUString& locationUrl,
1738 const OUString& registeredLocationUrl)
1739 /* throw ( InvalidRegistryException,
1740 MergeConflictException,
1741 CannotRegisterImplementationException, RuntimeException ) */
1743 Reference < XSimpleRegistry > xReg =
1744 createTemporarySimpleRegistry( xSMgr, xCtx );
1745 Reference < XRegistryKey > xSourceKey;
1747 if (xAct.is() && xReg.is() && xDest.is())
1751 xReg->open(OUString() /* in mem */, sal_False, sal_True);
1753 { // only necessary for deleting the temporary variable of rootkey
1754 xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1757 bool bSuccess =
1758 xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1759 if ( bSuccess )
1761 prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1763 xSourceKey->closeKey();
1765 xSourceKey = xReg->getRootKey();
1766 Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1767 stoc_impreg::mergeKeys( xDestKey, xSourceKey );
1768 xDestKey->closeKey();
1769 xSourceKey->closeKey();
1771 else
1773 throw CannotRegisterImplementationException(
1774 "ImplementationRegistration::doRegistration() component registration signaled failure" );
1777 // Cleanup Source registry.
1778 if ( xSourceKey->isValid() )
1779 xSourceKey->closeKey();
1781 catch(CannotRegisterImplementationException&)
1783 if ( xSourceKey->isValid() )
1784 xSourceKey->closeKey();
1785 // and throw again
1786 throw;
1793 Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1794 const Reference< XMultiComponentFactory > &rSMgr,
1795 const Reference < XComponentContext > & xCtx)
1798 Reference < XSimpleRegistry > xReg(
1799 rSMgr->createInstanceWithContext(
1800 spool().com_sun_star_registry_SimpleRegistry, xCtx ),
1801 UNO_QUERY);
1802 OSL_ASSERT( xReg.is() );
1803 return xReg;
1808 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1809 com_sun_star_comp_stoc_ImplementationRegistration_get_implementation(
1810 css::uno::XComponentContext *context,
1811 css::uno::Sequence<css::uno::Any> const &)
1813 return cppu::acquire(new ImplementationRegistration(context));
1816 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */