Update ooo320-m1
[ooovba.git] / stoc / source / implementationregistration / implreg.cxx
blob2b4139590d1f0ca4ba770f0eecd5d676163959b9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: implreg.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_stoc.hxx"
33 #include <stdlib.h>
34 #include <string.h>
35 #include <list>
37 #include <unistd.h>
38 #include <cppuhelper/queryinterface.hxx>
39 #include <cppuhelper/factory.hxx>
40 #include <cppuhelper/weak.hxx>
41 #include <cppuhelper/servicefactory.hxx>
42 #ifndef _CPPUHELPER_IMPLBASE3_HXX
43 #include <cppuhelper/implbase3.hxx>
44 #endif
45 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
46 #include <cppuhelper/implementationentry.hxx>
47 #endif
49 #include <uno/mapping.hxx>
50 #include <osl/thread.h>
52 #include <rtl/ustring.hxx>
53 #include <rtl/ustrbuf.hxx>
54 #include <rtl/strbuf.hxx>
55 #include <osl/process.h>
57 #include <com/sun/star/lang/XServiceInfo.hpp>
58 #include <com/sun/star/lang/XInitialization.hpp>
59 #include <com/sun/star/loader/XImplementationLoader.hpp>
60 #include <com/sun/star/registry/XImplementationRegistration2.hpp>
61 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
62 #include <com/sun/star/reflection/XServiceTypeDescription.hpp>
63 #include <com/sun/star/beans/XPropertySet.hpp>
64 #include "com/sun/star/uno/RuntimeException.hpp"
66 #include "mergekeys.hxx"
68 #if defined(SAL_W32) || defined(SAL_OS2)
69 #include <io.h>
70 #endif
72 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
75 using namespace com::sun::star;
76 using namespace com::sun::star::uno;
77 using namespace com::sun::star::loader;
78 using namespace com::sun::star::beans;
79 using namespace com::sun::star::lang;
80 using namespace com::sun::star::registry;
81 using namespace cppu;
82 using namespace rtl;
83 using namespace osl;
86 #define IMPLNAME "com.sun.star.comp.stoc.ImplementationRegistration"
87 #define SERVICENAME "com.sun.star.registry.ImplementationRegistration"
88 namespace stoc_impreg
90 struct StringPool
92 OUString sImplementationName;
93 OUString sServiceName;
94 OUString TMP;
95 OUString TEMP;
96 OUString slash_UNO_slash_REGISTRY_LINKS;
97 OUString slash_IMPLEMENTATIONS;
98 OUString slash_UNO;
99 OUString slash_UNO_slash_SERVICES;
100 OUString slash_UNO_slash_SINGLETONS;
101 OUString slash_SERVICES;
102 OUString slash_UNO_slash_LOCATION;
103 OUString slash_UNO_slash_ACTIVATOR;
104 OUString colon_old;
105 OUString com_sun_star_registry_SimpleRegistry;
106 OUString Registry;
107 StringPool()
108 : sImplementationName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) )
109 , sServiceName( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) )
110 , TMP( RTL_CONSTASCII_USTRINGPARAM( "TMP" ) )
111 , TEMP( RTL_CONSTASCII_USTRINGPARAM( "TEMP" ) )
112 , slash_UNO_slash_REGISTRY_LINKS( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS"))
113 , slash_IMPLEMENTATIONS( RTL_CONSTASCII_USTRINGPARAM( "/IMPLEMENTATIONS" ) )
114 , slash_UNO( RTL_CONSTASCII_USTRINGPARAM("/UNO"))
115 , slash_UNO_slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES"))
116 , slash_UNO_slash_SINGLETONS( RTL_CONSTASCII_USTRINGPARAM("/UNO/SINGLETONS"))
117 , slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") )
118 , slash_UNO_slash_LOCATION( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") )
119 , slash_UNO_slash_ACTIVATOR( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") )
120 , colon_old( RTL_CONSTASCII_USTRINGPARAM(":old"))
121 , com_sun_star_registry_SimpleRegistry(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry") )
122 , Registry( RTL_CONSTASCII_USTRINGPARAM("Registry") )
124 private:
125 StringPool( const StringPool & );
128 const StringPool &spool()
130 static StringPool *pPool = 0;
131 if( ! pPool )
133 MutexGuard guard( Mutex::getGlobalMutex() );
134 if( ! pPool )
136 static StringPool pool;
137 pPool = &pool;
140 return *pPool;
144 extern rtl_StandardModuleCount g_moduleCount;
146 namespace stoc_bootstrap
148 Sequence< OUString > impreg_getSupportedServiceNames()
150 static Sequence < OUString > *pNames = 0;
151 if( ! pNames )
153 MutexGuard guard( Mutex::getGlobalMutex() );
154 if( !pNames )
156 static Sequence< OUString > seqNames(1);
157 seqNames.getArray()[0] = stoc_impreg::spool().sServiceName;
158 pNames = &seqNames;
161 return *pNames;
164 OUString impreg_getImplementationName()
166 return stoc_impreg::spool().sImplementationName;
170 namespace stoc_impreg
172 //*************************************************************************
173 // static deleteAllLinkReferences()
175 static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
176 const Reference < XRegistryKey >& xSource)
177 // throw ( InvalidRegistryException, RuntimeException )
179 Reference < XRegistryKey > xKey = xSource->openKey(
180 spool().slash_UNO_slash_REGISTRY_LINKS );
182 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
184 Sequence<OUString> linkNames = xKey->getAsciiListValue();
186 if (linkNames.getLength())
188 const OUString* pLinkNames = linkNames.getConstArray();
190 OUString aLinkName;
191 OUString aLinkParent;
192 Reference < XRegistryKey > xLinkParent;
193 const sal_Unicode* pTmpName = NULL;
194 const sal_Unicode* pShortName = NULL;
195 sal_Int32 sEnd = 0;
197 for (sal_Int32 i = 0; i < linkNames.getLength(); i++)
199 aLinkName = pLinkNames[i];
201 pTmpName = aLinkName.getStr();
203 if (pTmpName[0] != L'/')
204 continue;
206 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
207 if ( nIndex == -1 )
208 pShortName = 0;
209 else
210 pShortName = pTmpName+nIndex;
212 while (pShortName && pShortName[1] == L'%')
214 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
215 if ( nIndex == -1 )
216 pShortName = 0;
217 else
218 pShortName += nIndex+2;
221 if (pShortName)
223 aLinkName = aLinkName.copy(0, pShortName - pTmpName);
226 xReg->getRootKey()->deleteLink(aLinkName);
228 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
230 aLinkParent = aLinkName.copy(0, sEnd);
232 while(aLinkParent.getLength())
234 xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
236 if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0))
238 aLinkName = aLinkParent;
240 xReg->getRootKey()->deleteKey(aLinkParent);
242 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
244 aLinkParent = aLinkName.copy(0, sEnd);
245 } else
247 break;
255 //*************************************************************************
256 // static prepareLink
258 static void prepareLink( const Reference < XSimpleRegistry > & xDest,
259 const Reference < XRegistryKey > & xSource,
260 const OUString& link)
261 // throw ( InvalidRegistryException, RuntimeException )
263 OUString linkRefName = xSource->getKeyName();
264 OUString linkName(link);
265 sal_Bool isRelativ = sal_False;
267 const sal_Unicode* pTmpName = link.getStr();
268 const sal_Unicode* pShortName;
269 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
270 if ( nIndex == -1 )
271 pShortName = 0;
272 else
273 pShortName = pTmpName+nIndex;
275 if (pTmpName[0] != L'/')
276 isRelativ = sal_True;
278 while (pShortName && pShortName[1] == L'%')
280 nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
281 if ( nIndex == -1 )
282 pShortName = 0;
283 else
284 pShortName += nIndex+2;
287 if (pShortName)
289 linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1);
290 linkName = link.copy(0, pShortName - pTmpName);
293 if (isRelativ)
294 xSource->createLink(linkName, linkRefName);
295 else
296 xDest->getRootKey()->createLink(linkName, linkRefName);
299 //*************************************************************************
300 // static searchImplForLink
302 static OUString searchImplForLink(
303 const Reference < XRegistryKey > & xRootKey,
304 const OUString& linkName,
305 const OUString& implName )
306 // throw ( InvalidRegistryException, RuntimeException )
308 const StringPool & pool = spool();
309 Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
310 if (xKey.is())
312 Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
313 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
314 OUString key_name( pool.slash_UNO + linkName );
316 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
320 Reference < XRegistryKey > xImplKey( pSubKeys[i] );
321 if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
323 OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
324 if (implName != oldImplName)
326 return oldImplName;
330 catch(InvalidRegistryException&)
336 return OUString();
339 //*************************************************************************
340 // static searchLinkTargetForImpl
342 static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
343 const OUString& linkName,
344 const OUString& implName)
345 // throw ( InvalidRegistryException, RuntimeException )
347 OUString ret;
349 // try
350 // {
351 const StringPool & pool = spool();
352 Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
354 if (xKey.is())
356 Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
358 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
359 Reference < XRegistryKey > xImplKey;
361 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
363 xImplKey = pSubKeys[i];
365 OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
366 OUString qualifiedLinkName( pool.slash_UNO );
367 qualifiedLinkName += linkName;
368 if (tmpImplName == implName &&
369 xImplKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK)
371 return xImplKey->getLinkTarget( qualifiedLinkName );
375 // }
376 // catch(InvalidRegistryException&)
377 // {
378 // }
380 return ret;
383 //*************************************************************************
384 // static createUniqueSubEntry
386 static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
387 const OUString& value)
388 // throw ( InvalidRegistryException, RuntimeException )
390 if (xSuperKey.is())
392 // try
393 // {
394 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
396 sal_Int32 length = 0;
397 sal_Bool bReady = sal_False;
399 Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
400 length = implEntries.getLength();
402 for (sal_Int32 i = 0; !bReady && (i < length); i++)
404 bReady = (implEntries.getConstArray()[i] == value);
407 if (bReady)
409 Sequence<OUString> implEntriesNew(length);
410 implEntriesNew.getArray()[0] = value;
412 for (sal_Int32 i=0, j=1; i < length; i++)
414 if (implEntries.getConstArray()[i] != value)
415 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
417 xSuperKey->setAsciiListValue(implEntriesNew);
418 } else
420 Sequence<OUString> implEntriesNew(length+1);
421 implEntriesNew.getArray()[0] = value;
423 for (sal_Int32 i = 0; i < length; i++)
425 implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i];
427 xSuperKey->setAsciiListValue(implEntriesNew);
429 } else
431 Sequence<OUString> implEntriesNew(1);
433 implEntriesNew.getArray()[0] = value;
435 xSuperKey->setAsciiListValue(implEntriesNew);
437 // }
438 // catch(InvalidRegistryException&)
439 // {
440 // }
444 //*************************************************************************
445 // static deleteSubEntry
447 static sal_Bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value)
448 // throw ( InvalidRegistryException, RuntimeException )
450 if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
452 Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
453 sal_Int32 length = implEntries.getLength();
454 sal_Int32 equals = 0;
455 sal_Bool hasNoImplementations = sal_False;
457 for (sal_Int32 i = 0; i < length; i++)
459 if (implEntries.getConstArray()[i] == value)
460 equals++;
463 if (equals == length)
465 hasNoImplementations = sal_True;
466 } else
468 Sequence<OUString> implEntriesNew(length - equals);
470 sal_Int32 j = 0;
471 for (sal_Int32 i = 0; i < length; i++)
473 if (implEntries.getConstArray()[i] != value)
475 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
478 xSuperKey->setAsciiListValue(implEntriesNew);
481 if (hasNoImplementations)
483 return sal_True;
486 return sal_False;
489 //*************************************************************************
490 // static prepareUserLink
492 static void prepareUserLink(const Reference < XSimpleRegistry >& xDest,
493 const OUString& linkName,
494 const OUString& linkTarget,
495 const OUString& implName)
496 // throw ( InvalidRegistryException, RuntimeException )
498 sal_Bool ret = sal_False;
500 Reference < XRegistryKey > xRootKey;
502 // try
503 // {
504 xRootKey = xDest->getRootKey();
506 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
508 OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
510 if (oldImplName.getLength())
512 createUniqueSubEntry(xDest->getRootKey()->createKey(
513 linkName + spool().colon_old ), oldImplName);
516 // }
517 // catch (InvalidRegistryException&)
518 // {
519 // }
521 // try
522 // {
523 if (xRootKey->isValid())
525 ret = xRootKey->createLink(linkName, linkTarget);
527 // }
528 // catch(InvalidRegistryException&)
529 // {
530 // }
532 // return ret;
535 //*************************************************************************
536 // static deleteUserLink
538 static void deletePathIfPossible(const Reference < XRegistryKey >& xRootKey,
539 const OUString& path)
543 Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
545 if (keyNames.getLength() == 0 &&
546 xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
548 xRootKey->deleteKey(path);
550 OUString tmpPath(path);
551 OUString newPath = tmpPath.copy(0, tmpPath.lastIndexOf('/'));
553 if (newPath.getLength() > 1)
554 deletePathIfPossible(xRootKey, newPath);
557 catch(InvalidRegistryException&)
563 //*************************************************************************
564 // static deleteUserLink
566 static void deleteUserLink(const Reference < XRegistryKey >& xRootKey,
567 const OUString& linkName,
568 const OUString& linkTarget,
569 const OUString& implName)
570 // throw ( InvalidRegistryException, RuntimeException )
572 sal_Bool bClean = sal_False;
574 if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
576 OUString tmpTarget = xRootKey->getLinkTarget(linkName);
578 if (tmpTarget == linkTarget)
580 xRootKey->deleteLink(linkName);
584 Reference < XRegistryKey > xOldKey = xRootKey->openKey(
585 linkName + spool().colon_old );
586 if (xOldKey.is())
588 sal_Bool hasNoImplementations = sal_False;
590 if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
592 Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
593 sal_Int32 length = implEntries.getLength();
594 sal_Int32 equals = 0;
596 for (sal_Int32 i = 0; i < length; i++)
598 if (implEntries.getConstArray()[i] == implName)
599 equals++;
602 if (equals == length)
604 hasNoImplementations = sal_True;
605 } else
607 OUString oldImpl;
609 if (length > equals + 1)
611 Sequence<OUString> implEntriesNew(length - equals - 1);
613 sal_Int32 j = 0;
614 sal_Bool first = sal_True;
615 for (sal_Int32 i = 0; i < length; i++)
617 if (implEntries.getConstArray()[i] != implName)
619 if (first)
621 oldImpl = implEntries.getConstArray()[i];
622 first = sal_False;
623 } else
625 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
630 xOldKey->setAsciiListValue(implEntriesNew);
631 } else
633 oldImpl = implEntries.getConstArray()[0];
635 xOldKey->closeKey();
636 xRootKey->deleteKey(xOldKey->getKeyName());
639 OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
640 if (oldTarget.getLength())
642 xRootKey->createLink(linkName, oldTarget);
646 if (hasNoImplementations)
648 bClean = sal_True;
649 hasNoImplementations = sal_False;
650 xOldKey->closeKey();
651 xRootKey->deleteKey(xOldKey->getKeyName());
654 } else
656 bClean = sal_True;
659 if (bClean)
661 OUString tmpName(linkName);
662 OUString path = tmpName.copy(0, tmpName.lastIndexOf('/'));
663 deletePathIfPossible(xRootKey, path);
667 //*************************************************************************
668 // static prepareUserKeys
670 static void prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
671 const Reference < XRegistryKey >& xUnoKey,
672 const Reference < XRegistryKey >& xKey,
673 const OUString& implName,
674 sal_Bool bRegister)
675 // throw ( InvalidRegistryException, RuntimeException )
677 sal_Bool hasSubKeys = sal_False;
679 Sequence<OUString> keyNames = xKey->getKeyNames();
681 OUString relativKey;
682 if (keyNames.getLength())
683 relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
685 if (keyNames.getLength() == 1 &&
686 xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
688 hasSubKeys = sal_True;
690 OUString linkTarget = xKey->getLinkTarget(relativKey);
691 OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
693 linkName = linkName + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + relativKey;
695 if (bRegister)
697 prepareUserLink(xDest, linkName, linkTarget, implName);
698 } else
700 deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
702 } else
704 Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
706 if (subKeys.getLength())
708 hasSubKeys = sal_True;
709 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
711 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
713 prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
718 if (! hasSubKeys)
720 OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
722 Reference < XRegistryKey > xRootKey = xDest->getRootKey();
723 if (bRegister)
725 createUniqueSubEntry(xRootKey->createKey(keyName), implName);
727 else
729 Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
730 if( rKey.is() )
732 deleteSubEntry(rKey, implName);
733 xRootKey->deleteKey(keyName);
736 OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
737 if( path.getLength() )
739 deletePathIfPossible(xRootKey, path);
743 return;
746 //*************************************************************************
747 // static deleteAllImplementations
749 static void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg,
750 const Reference < XRegistryKey >& xSource,
751 const OUString& locationUrl,
752 std::list<OUString> & implNames)
753 // throw (InvalidRegistryException, RuntimeException)
755 Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
757 if (subKeys.getLength() > 0)
759 const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
760 Reference < XRegistryKey > xImplKey;
761 sal_Bool hasLocationUrl = sal_False;
763 const StringPool &pool = spool();
764 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
766 xImplKey = pSubKeys[i];
767 Reference < XRegistryKey > xKey = xImplKey->openKey(
768 pool.slash_UNO_slash_LOCATION );
770 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
772 if (xKey->getAsciiValue() == locationUrl)
774 hasLocationUrl = sal_True;
776 OUString implName(xImplKey->getKeyName().getStr() + 1);
777 sal_Int32 firstDot = implName.indexOf('/');
779 if (firstDot >= 0)
780 implName = implName.copy(firstDot + 1);
782 implNames.push_back(implName);
784 deleteAllLinkReferences(xReg, xImplKey);
786 xKey = xImplKey->openKey( pool.slash_UNO );
787 if (xKey.is())
789 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
791 if (subKeys2.getLength())
793 const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
795 for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
797 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
798 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
799 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
800 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
801 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
803 prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, sal_False);
811 if (hasLocationUrl)
813 hasLocationUrl = sal_False;
814 xImplKey->closeKey();
815 xReg->getRootKey()->deleteKey(xImplKey->getKeyName());
819 subKeys = xSource->openKeys();
820 if (subKeys.getLength() == 0)
822 xSource->closeKey();
823 xReg->getRootKey()->deleteKey(xSource->getKeyName());
825 } else
827 xSource->closeKey();
828 xReg->getRootKey()->deleteKey(xSource->getKeyName());
832 //==================================================================================================
833 static void delete_all_singleton_entries(
834 Reference < registry::XRegistryKey > const & xSingletons_section,
835 ::std::list< OUString > const & impl_names )
836 // throw (InvalidRegistryException, RuntimeException)
838 Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
839 Reference< registry::XRegistryKey > const * subkeys = singletons.getConstArray();
840 for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
842 Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
843 Reference< registry::XRegistryKey > xRegisteredImplNames(
844 xSingleton->openKey( OUSTR("REGISTERED_BY") ) );
845 if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
847 Sequence< OUString > registered_implnames;
850 registered_implnames = xRegisteredImplNames->getAsciiListValue();
852 catch (registry::InvalidValueException &)
855 OUString const * p = registered_implnames.getConstArray();
856 sal_Int32 nOrigRegLength = registered_implnames.getLength();
857 sal_Int32 nNewLength = nOrigRegLength;
858 for ( sal_Int32 n = nOrigRegLength; n--; )
860 OUString const & registered_implname = p[ n ];
862 ::std::list< OUString >::const_iterator iPos( impl_names.begin() );
863 ::std::list< OUString >::const_iterator const iEnd( impl_names.end() );
864 for ( ; iPos != iEnd; ++iPos )
866 if (iPos->equals( registered_implname ))
868 registered_implnames[ n ] = p[ nNewLength -1 ];
869 --nNewLength;
874 if (nNewLength != nOrigRegLength)
876 if (0 == nNewLength)
878 // remove whole entry
879 xRegisteredImplNames->closeKey();
880 xSingleton->deleteKey( OUSTR("REGISTERED_BY") );
881 // registry key cannot provide its relative name, only absolute :(
882 OUString abs( xSingleton->getKeyName() );
883 xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
885 else
887 registered_implnames.realloc( nNewLength );
888 xRegisteredImplNames->setAsciiListValue( registered_implnames );
895 //*************************************************************************
896 // static deleteAllServiceEntries
898 static void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg,
899 const Reference < XRegistryKey >& xSource,
900 const OUString& implName)
901 // throw ( InvalidRegistryException, RuntimeException )
903 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
905 if (subKeys.getLength() > 0)
907 const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
908 Reference < XRegistryKey > xServiceKey;
909 sal_Bool hasNoImplementations = sal_False;
911 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
913 xServiceKey = pSubKeys[i];
915 if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
917 Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
918 sal_Int32 length = implEntries.getLength();
919 sal_Int32 equals = 0;
921 for (sal_Int32 j = 0; j < length; j++)
923 if (implEntries.getConstArray()[j] == implName)
924 equals++;
927 if (equals == length)
929 hasNoImplementations = sal_True;
930 } else
932 if (equals > 0)
934 Sequence<OUString> implEntriesNew(length-equals);
936 sal_Int32 j = 0;
937 for (sal_Int32 k = 0; k < length; k++)
939 if (implEntries.getConstArray()[k] != implName)
941 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[k];
945 xServiceKey->setAsciiListValue(implEntriesNew);
950 if (hasNoImplementations)
952 hasNoImplementations = sal_False;
953 xServiceKey->closeKey();
954 xReg->getRootKey()->deleteKey(xServiceKey->getKeyName());
958 subKeys = xSource->openKeys();
959 if (subKeys.getLength() == 0)
961 xSource->closeKey();
962 xReg->getRootKey()->deleteKey(xSource->getKeyName());
964 } else
966 xSource->closeKey();
967 xReg->getRootKey()->deleteKey(xSource->getKeyName());
971 //--------------------------------------------------------------------------------------------------
972 static bool is_supported_service(
973 OUString const & service_name,
974 Reference< reflection::XServiceTypeDescription > const & xService_td )
976 if (xService_td->getName().equals( service_name ))
977 return true;
978 Sequence< Reference< reflection::XServiceTypeDescription > > seq(
979 xService_td->getMandatoryServices() );
980 Reference< reflection::XServiceTypeDescription > const * p = seq.getConstArray();
981 for ( sal_Int32 nPos = seq.getLength(); nPos--; )
983 if (is_supported_service( service_name, p[ nPos ] ))
984 return true;
986 return false;
989 //--------------------------------------------------------------------------------------------------
990 static void insert_singletons(
991 Reference< registry::XSimpleRegistry > const & xDest,
992 Reference< registry::XRegistryKey > const & xImplKey,
993 Reference< XComponentContext > const & xContext )
994 // throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
996 // singletons
997 Reference< registry::XRegistryKey > xKey( xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
998 if (xKey.is() && xKey->isValid())
1000 OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
1001 // singleton entries
1002 Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
1003 Reference< registry::XRegistryKey > const * p = xSingletons_section.getConstArray();
1004 for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
1006 Reference< registry::XRegistryKey > const & xSingleton = p[ nPos ];
1007 OUString singleton_name(
1008 xSingleton->getKeyName().copy(
1009 implname.getLength() + sizeof ("/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
1010 OUString service_name( xSingleton->getStringValue() );
1012 OUString keyname( OUSTR("/SINGLETONS/") + singleton_name );
1013 Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
1014 if (xKey2.is() && xKey2->isValid())
1018 OUString existing_name( xKey2->getStringValue() );
1019 if (! existing_name.equals( service_name ))
1021 Reference< container::XHierarchicalNameAccess > xTDMgr;
1022 OUString the_tdmgr =
1023 OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
1024 xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
1025 if (! xTDMgr.is())
1027 throw RuntimeException(
1028 OUSTR("cannot get singleton ") + the_tdmgr,
1029 Reference< XInterface >() );
1033 Reference< reflection::XServiceTypeDescription > xExistingService_td;
1034 xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
1035 if (! xExistingService_td.is())
1037 throw RuntimeException(
1038 OUSTR("cannot get service type description: ") + existing_name,
1039 Reference< XInterface >() );
1042 // everything's fine if existing service entry supports the one
1043 // to be registered
1044 if (! is_supported_service( service_name, xExistingService_td ))
1046 OUStringBuffer buf( 64 );
1047 buf.appendAscii(
1048 RTL_CONSTASCII_STRINGPARAM("existing singleton service (") );
1049 buf.append( singleton_name );
1050 buf.append( (sal_Unicode)'=' );
1051 buf.append( existing_name );
1052 buf.appendAscii(
1053 RTL_CONSTASCII_STRINGPARAM(") does not support given one: ") );
1054 buf.append( service_name );
1055 throw registry::CannotRegisterImplementationException(
1056 buf.makeStringAndClear(), Reference< XInterface >() );
1059 catch (container::NoSuchElementException & exc)
1061 throw RuntimeException(
1062 OUSTR("cannot get service type description: ") + exc.Message,
1063 Reference< XInterface >() );
1067 catch (registry::InvalidValueException &)
1069 // repair
1070 xKey2->setStringValue( service_name );
1073 else
1075 // insert singleton entry
1076 xKey2 = xDest->getRootKey()->createKey( keyname );
1077 xKey2->setStringValue( service_name );
1080 Reference< registry::XRegistryKey > xRegisteredImplNames(
1081 xKey2->openKey( OUSTR("REGISTERED_BY") ) );
1082 if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
1084 // create
1085 xRegisteredImplNames = xKey2->createKey( OUSTR("REGISTERED_BY") );
1088 Sequence< OUString > implnames;
1091 implnames = xRegisteredImplNames->getAsciiListValue();
1093 catch (registry::InvalidValueException &)
1096 // check implname is already in
1097 sal_Int32 nPos_implnames = implnames.getLength();
1098 OUString const * pImplnames = implnames.getConstArray();
1099 while (nPos_implnames--)
1101 if (implname.equals( pImplnames[ nPos_implnames ] ))
1102 break;
1104 if (nPos_implnames < 0)
1106 // append and write back
1107 implnames.realloc( implnames.getLength() +1 );
1108 implnames[ implnames.getLength() -1 ] = implname;
1109 xRegisteredImplNames->setAsciiListValue( implnames );
1116 //*************************************************************************
1117 // static prepareRegistry
1119 static void prepareRegistry(
1120 const Reference < XSimpleRegistry >& xDest,
1121 const Reference < XRegistryKey >& xSource,
1122 const OUString& implementationLoaderUrl,
1123 const OUString& locationUrl,
1124 Reference< XComponentContext > const & xContext )
1125 // throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
1127 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1129 if (!subKeys.getLength())
1131 throw InvalidRegistryException(
1132 OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): source registry is empty" ) ),
1133 Reference< XInterface > () );
1136 const StringPool & pool = spool();
1138 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1139 Reference < XRegistryKey > xImplKey;
1141 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1143 xImplKey = pSubKeys[i];
1145 Reference < XRegistryKey > xKey = xImplKey->openKey(
1146 pool.slash_UNO_slash_SERVICES );
1148 if (xKey.is())
1150 // update entries in SERVICES section
1151 Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
1152 OUString implName;
1154 if (serviceKeys.getLength())
1156 const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
1158 implName = OUString(xImplKey->getKeyName().getStr() + 1);
1159 sal_Int32 firstDot = implName.indexOf('/');
1161 if (firstDot >= 0)
1162 implName = implName.copy(firstDot + 1);
1164 sal_Int32 offset = xKey->getKeyName().getLength() + 1;
1166 for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
1168 OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
1170 createUniqueSubEntry(
1171 xDest->getRootKey()->createKey(
1172 pool.slash_SERVICES + serviceName ),
1173 implName);
1177 else
1179 throw InvalidRegistryException(
1180 OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): no service names given by component" ) ),
1181 Reference< XInterface > () );
1184 xKey = xImplKey->openKey( pool.slash_UNO );
1185 if (xKey.is())
1187 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
1189 if (subKeys2.getLength())
1191 const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
1193 for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
1195 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
1196 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
1197 pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
1199 prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, sal_True);
1205 // update LOCATION entry
1206 xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
1208 if (xKey.is())
1210 xKey->setAsciiValue(locationUrl);
1213 // update ACTIVATOR entry
1214 xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
1216 if (xKey.is())
1218 xKey->setAsciiValue(implementationLoaderUrl);
1221 xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
1223 if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
1225 // update link entries in REGISTRY_LINKS section
1226 Sequence<OUString> linkNames = xKey->getAsciiListValue();
1228 if (linkNames.getLength())
1230 const OUString* pLinkNames = linkNames.getConstArray();
1232 for (sal_Int32 j = 0; j < linkNames.getLength(); j++)
1234 prepareLink(xDest, xImplKey, pLinkNames[j]);
1240 insert_singletons( xDest, xImplKey, xContext );
1245 static void findImplementations( const Reference < XRegistryKey > & xSource,
1246 std::list <OUString>& implNames)
1248 sal_Bool isImplKey = sal_False;
1252 Reference < XRegistryKey > xKey = xSource->openKey(
1253 spool().slash_UNO_slash_SERVICES );
1255 if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
1257 isImplKey = sal_True;
1259 OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace('/', '.').getStr();
1260 sal_Int32 firstDot = implName.indexOf('.');
1262 if (firstDot >= 0)
1263 implName = implName.copy(firstDot + 1);
1265 implNames.push_back(implName);
1268 catch(InvalidRegistryException&)
1272 if (isImplKey) return;
1276 Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1278 if (subKeys.getLength() > 0)
1280 const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1282 for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1284 findImplementations(pSubKeys[i], implNames);
1289 catch(InvalidRegistryException&)
1295 class ImplementationRegistration
1296 : public WeakImplHelper3< XImplementationRegistration2, XServiceInfo, XInitialization >
1298 public:
1299 ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
1300 ~ImplementationRegistration();
1302 // XServiceInfo
1303 OUString SAL_CALL getImplementationName() throw(RuntimeException);
1304 sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException);
1305 Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(RuntimeException);
1307 // XImplementationRegistration
1308 virtual void SAL_CALL registerImplementation(
1309 const OUString& implementationLoader,
1310 const OUString& location,
1311 const Reference < XSimpleRegistry > & xReg)
1312 throw( CannotRegisterImplementationException, RuntimeException );
1314 virtual sal_Bool SAL_CALL revokeImplementation(
1315 const OUString& location,
1316 const Reference < XSimpleRegistry >& xReg)
1317 throw( RuntimeException );
1319 virtual Sequence< OUString > SAL_CALL getImplementations(
1320 const OUString& implementationLoader,
1321 const OUString& location)
1322 throw( RuntimeException );
1323 virtual Sequence< OUString > SAL_CALL checkInstantiation(
1324 const OUString& implementationName)
1325 throw( RuntimeException );
1327 // XImplementationRegistration2
1328 virtual void SAL_CALL registerImplementationWithLocation(
1329 const OUString& implementationLoader,
1330 const OUString& location,
1331 const OUString& registeredLocation,
1332 const Reference < XSimpleRegistry > & xReg)
1333 throw( CannotRegisterImplementationException, RuntimeException );
1335 // XInitialization
1336 virtual void SAL_CALL initialize(
1337 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
1338 throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
1340 private: // helper methods
1341 void prepareRegister(
1342 const OUString& implementationLoader,
1343 const OUString& location,
1344 const OUString& registeredLocation,
1345 const Reference < XSimpleRegistry > & xReg);
1346 // throw( CannotRegisterImplementationException, RuntimeException )
1348 static void doRegister( const Reference < XMultiComponentFactory >& xSMgr,
1349 const Reference < XComponentContext > &xCtx,
1350 const Reference < XImplementationLoader >& xAct,
1351 const Reference < XSimpleRegistry >& xDest,
1352 const OUString& implementationLoaderUrl,
1353 const OUString& locationUrl,
1354 const OUString& registeredLocationUrl);
1355 /* throw ( InvalidRegistryException,
1356 MergeConflictException,
1357 CannotRegisterImplementationException, RuntimeException ) */
1359 static void doRevoke( const Reference < XSimpleRegistry >& xDest,
1360 const OUString& locationUrl );
1361 // throw( InvalidRegistryException, RuntimeException )
1362 Reference< XSimpleRegistry > getRegistryFromServiceManager();
1364 static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
1365 const Reference< XMultiComponentFactory > &rSMgr,
1366 const Reference < XComponentContext > & rCtx );
1368 private: // members
1369 Reference < XMultiComponentFactory > m_xSMgr;
1370 Reference < XComponentContext > m_xCtx;
1373 //*************************************************************************
1374 // ImplementationRegistration()
1376 ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
1377 : m_xSMgr( xCtx->getServiceManager() )
1378 , m_xCtx( xCtx )
1380 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
1383 //*************************************************************************
1384 // ~ImplementationRegistration()
1386 ImplementationRegistration::~ImplementationRegistration()
1388 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
1392 // XServiceInfo
1393 OUString ImplementationRegistration::getImplementationName() throw(RuntimeException)
1395 return stoc_bootstrap::impreg_getImplementationName();
1398 // XServiceInfo
1399 sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw(RuntimeException)
1401 Sequence< OUString > aSNL = getSupportedServiceNames();
1402 const OUString * pArray = aSNL.getConstArray();
1403 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1404 if( pArray[i] == ServiceName )
1405 return sal_True;
1406 return sal_False;
1409 // XServiceInfo
1410 Sequence< OUString > ImplementationRegistration::getSupportedServiceNames(void) throw(RuntimeException)
1412 return stoc_bootstrap::impreg_getSupportedServiceNames();
1415 Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
1417 Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1418 Reference < XSimpleRegistry > xRegistry;
1420 if( xPropSet.is() ) {
1422 try { // the implementation does not support XIntrospectionAccess !
1424 Any aAny = xPropSet->getPropertyValue( spool().Registry );
1426 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1427 aAny >>= xRegistry;
1430 catch( UnknownPropertyException & ) {
1431 // empty reference is error signal !
1435 return xRegistry;
1439 //************************************************************************
1440 // XInitialization
1442 void ImplementationRegistration::initialize(
1443 const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs )
1444 throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1447 if( aArgs.getLength() != 4 ) {
1448 OUStringBuffer buf;
1449 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1450 "ImplementationRegistration::initialize() expects 4 parameters, got "));
1451 buf.append( (sal_Int32) aArgs.getLength() );
1452 throw IllegalArgumentException( buf.makeStringAndClear(),
1453 Reference<XInterface > (),
1454 0 );
1457 Reference< XImplementationLoader > rLoader;
1458 OUString loaderServiceName;
1459 OUString locationUrl;
1460 Reference< XSimpleRegistry > rReg;
1462 // 1st argument : An instance of an implementation loader
1463 if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1464 aArgs.getConstArray()[0] >>= rLoader;
1466 if( !rLoader.is()) {
1467 OUStringBuffer buf;
1468 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1469 "ImplementationRegistration::initialize() invalid first parameter,"
1470 "expected " ) );
1471 buf.append( getCppuType( &rLoader ).getTypeName() );
1472 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", got " ) );
1473 buf.append( aArgs.getConstArray()[0].getValueTypeName() );
1474 throw IllegalArgumentException( buf.makeStringAndClear(),
1475 Reference< XInterface > (),
1476 0 );
1479 // 2nd argument : The service name of the loader. This name is written into the registry
1480 if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
1481 aArgs.getConstArray()[1] >>= loaderServiceName;
1483 if( ! loaderServiceName.getLength() ) {
1484 OUStringBuffer buf;
1485 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1486 "ImplementationRegistration::initialize() invalid second parameter,"
1487 "expected string, got " ) );
1488 buf.append( aArgs.getConstArray()[1].getValueTypeName() );
1489 throw IllegalArgumentException( buf.makeStringAndClear(),
1490 Reference< XInterface > (),
1491 0 );
1494 // 3rd argument : The file name of the dll, that contains the loader
1495 if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
1496 aArgs.getConstArray()[2] >>= locationUrl;
1498 if( ! locationUrl.getLength() ) {
1499 OUStringBuffer buf;
1500 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1501 "ImplementationRegistration::initialize() invalid third parameter,"
1502 "expected string, got " ) );
1503 buf.append( aArgs.getConstArray()[2].getValueTypeName() );
1504 throw IllegalArgumentException( buf.makeStringAndClear(),
1505 Reference< XInterface > (),
1506 0 );
1509 // 4th argument : The registry, the service should be written to
1510 if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1511 aArgs.getConstArray()[3] >>= rReg;
1514 if( !rReg.is() ) {
1515 rReg = getRegistryFromServiceManager();
1516 if( !rReg.is() ) {
1517 OUStringBuffer buf;
1518 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1519 "ImplementationRegistration::initialize() invalid fourth parameter,"
1520 "expected " ));
1521 buf.append( getCppuType( &rReg ).getTypeName() );
1522 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", got " ) );
1523 buf.append( aArgs.getConstArray()[3].getValueTypeName() );
1524 throw IllegalArgumentException( buf.makeStringAndClear(),
1525 Reference< XInterface > (),
1526 0 );
1530 doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
1535 //*************************************************************************
1536 // virtual function registerImplementationWithLocation of XImplementationRegistration2
1538 void ImplementationRegistration::registerImplementationWithLocation(
1539 const OUString& implementationLoaderUrl,
1540 const OUString& locationUrl,
1541 const OUString& registeredLocationUrl,
1542 const Reference < XSimpleRegistry > & xReg)
1543 throw( CannotRegisterImplementationException, RuntimeException )
1545 prepareRegister(
1546 implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
1549 // helper function
1550 void ImplementationRegistration::prepareRegister(
1551 const OUString& implementationLoaderUrl,
1552 const OUString& locationUrl,
1553 const OUString& registeredLocationUrl,
1554 const Reference < XSimpleRegistry > & xReg)
1555 // throw( CannotRegisterImplementationException, RuntimeException )
1557 OUString implLoaderUrl(implementationLoaderUrl);
1558 OUString activatorName;
1560 if (implementationLoaderUrl.getLength() > 0)
1562 OUString tmpActivator(implementationLoaderUrl);
1563 sal_Int32 nIndex = 0;
1564 activatorName = tmpActivator.getToken(0, ':', nIndex );
1565 } else
1567 // check locationUrl to find out what kind of loader is needed
1568 // set iimplLoaderUrl
1571 if( m_xSMgr.is() ) {
1574 Reference < XImplementationLoader > xAct(
1575 m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1576 if (xAct.is())
1578 Reference < XSimpleRegistry > xRegistry;
1580 if (xReg.is())
1582 // registry supplied by user
1583 xRegistry = xReg;
1585 else
1587 xRegistry = getRegistryFromServiceManager();
1590 if ( xRegistry.is())
1592 doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implLoaderUrl,
1593 locationUrl, registeredLocationUrl);
1596 else
1598 OUStringBuffer buf( 128 );
1599 buf.appendAscii( "ImplementationRegistration::registerImplementation() - The service " );
1600 buf.append( activatorName );
1601 buf.appendAscii( " cannot be instantiated\n" );
1602 throw CannotRegisterImplementationException(
1603 buf.makeStringAndClear(), Reference< XInterface > () );
1606 catch( CannotRegisterImplementationException & )
1608 throw;
1610 catch( InvalidRegistryException & e )
1612 OUStringBuffer buf;
1613 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1614 "ImplementationRegistration::registerImplementation() "
1615 "InvalidRegistryException during registration (" ));
1616 buf.append( e.Message );
1617 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1618 throw CannotRegisterImplementationException(
1619 buf.makeStringAndClear(), Reference< XInterface > () );
1621 catch( MergeConflictException & e )
1623 OUStringBuffer buf;
1624 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1625 "ImplementationRegistration::registerImplementation() "
1626 "MergeConflictException during registration (" ));
1627 buf.append( e.Message );
1628 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1629 throw CannotRegisterImplementationException(
1630 buf.makeStringAndClear(), Reference< XInterface > () );
1633 else
1635 throw CannotRegisterImplementationException(
1636 OUString(RTL_CONSTASCII_USTRINGPARAM(
1637 "ImplementationRegistration::registerImplementation() "
1638 "no componentcontext available to instantiate loader")),
1639 Reference< XInterface > () );
1643 //*************************************************************************
1644 // virtual function registerImplementation of XImplementationRegistration
1646 void ImplementationRegistration::registerImplementation(
1647 const OUString& implementationLoaderUrl,
1648 const OUString& locationUrl,
1649 const Reference < XSimpleRegistry > & xReg)
1650 throw( CannotRegisterImplementationException, RuntimeException )
1652 prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1656 //*************************************************************************
1657 // virtual function revokeImplementation of XImplementationRegistration
1659 sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
1660 const Reference < XSimpleRegistry >& xReg)
1661 throw ( RuntimeException )
1663 sal_Bool ret = sal_False;
1665 Reference < XSimpleRegistry > xRegistry;
1667 if (xReg.is()) {
1668 xRegistry = xReg;
1670 else {
1671 Reference < XPropertySet > xPropSet = Reference< XPropertySet >::query( m_xSMgr );
1672 if( xPropSet.is() ) {
1673 try {
1674 Any aAny = xPropSet->getPropertyValue( spool().Registry );
1676 if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
1678 aAny >>= xRegistry;
1681 catch ( UnknownPropertyException & ) {
1686 if (xRegistry.is())
1690 doRevoke(xRegistry, location);
1691 ret = sal_True;
1693 catch( InvalidRegistryException & )
1695 // no way to transport the error, as no exception is specified and a runtime
1696 // exception is not appropriate.
1697 OSL_ENSURE( 0 , "InvalidRegistryException during revokeImplementation" );
1701 return ret;
1704 //*************************************************************************
1705 // virtual function getImplementations of XImplementationRegistration
1707 Sequence< OUString > ImplementationRegistration::getImplementations(
1708 const OUString & implementationLoaderUrl,
1709 const OUString & locationUrl)
1710 throw ( RuntimeException )
1712 OUString implLoaderUrl(implementationLoaderUrl);
1713 OUString activatorName;
1715 if (implementationLoaderUrl.getLength() > 0)
1717 OUString tmpActivator(implementationLoaderUrl);
1718 sal_Int32 nIndex = 0;
1719 activatorName = tmpActivator.getToken(0, ':', nIndex );
1720 } else
1722 // check locationUrl to find out what kind of loader is needed
1723 // set implLoaderUrl
1726 if( m_xSMgr.is() ) {
1728 Reference < XImplementationLoader > xAct(
1729 m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1731 if (xAct.is())
1734 Reference < XSimpleRegistry > xReg =
1735 createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1737 if (xReg.is())
1741 xReg->open(OUString() /* in mem */, sal_False, sal_True);
1742 Reference < XRegistryKey > xImpl;
1744 { // only necessary for deleting the temporary variable of rootkey
1745 xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1747 if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1749 std::list <OUString> implNames;
1751 findImplementations(xImpl, implNames);
1753 if (!implNames.empty())
1755 std::list<OUString>::const_iterator iter = implNames.begin();
1757 Sequence<OUString> seqImpl(implNames.size());
1758 OUString *pImplNames = seqImpl.getArray();
1760 sal_Int32 index = 0;
1761 while (iter != implNames.end())
1763 pImplNames[index] = *iter;
1764 index++;
1765 ++iter;
1768 xImpl->closeKey();
1769 return seqImpl;
1773 xImpl->closeKey();
1775 catch(MergeConflictException&)
1778 catch(InvalidRegistryException&)
1785 return Sequence<OUString>();
1788 //*************************************************************************
1789 // virtual function checkInstantiation of XImplementationRegistration
1791 Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
1792 throw ( RuntimeException )
1794 OSL_ENSURE( sal_False, "ImplementationRegistration::checkInstantiation not implemented" );
1795 return Sequence<OUString>();
1798 //*************************************************************************
1799 // helper function doRegistration
1802 void ImplementationRegistration::doRevoke(
1803 const Reference < XSimpleRegistry >& xDest,
1804 const OUString& locationUrl)
1805 // throw ( InvalidRegistryException, RuntimeException )
1807 if( xDest.is() )
1809 std::list<OUString> aNames;
1811 const StringPool &pool = spool();
1812 Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1814 Reference < XRegistryKey > xKey =
1815 xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
1816 if (xKey.is() && xKey->isValid())
1818 deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1821 xKey = xRootKey->openKey( pool.slash_SERVICES );
1822 if (xKey.is())
1824 std::list<OUString>::const_iterator iter = aNames.begin();
1826 while (iter != aNames.end())
1828 deleteAllServiceEntries(xDest, xKey, *iter);
1829 ++iter;
1833 xKey = xRootKey->openKey( OUSTR("/SINGLETONS") );
1834 if (xKey.is() && xKey->isValid())
1836 delete_all_singleton_entries( xKey, aNames );
1839 if (xRootKey.is())
1840 xRootKey->closeKey();
1841 if (xKey.is() && xKey->isValid() )
1842 xKey->closeKey();
1846 void ImplementationRegistration::doRegister(
1847 const Reference< XMultiComponentFactory > & xSMgr,
1848 const Reference< XComponentContext > &xCtx,
1849 const Reference < XImplementationLoader > & xAct,
1850 const Reference < XSimpleRegistry >& xDest,
1851 const OUString& implementationLoaderUrl,
1852 const OUString& locationUrl,
1853 const OUString& registeredLocationUrl)
1854 /* throw ( InvalidRegistryException,
1855 MergeConflictException,
1856 CannotRegisterImplementationException, RuntimeException ) */
1858 Reference < XSimpleRegistry > xReg =
1859 createTemporarySimpleRegistry( xSMgr, xCtx );
1860 Reference < XRegistryKey > xSourceKey;
1862 if (xAct.is() && xReg.is() && xDest.is())
1866 xReg->open(OUString() /* in mem */, sal_False, sal_True);
1868 { // only necessary for deleting the temporary variable of rootkey
1869 xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1872 sal_Bool bSuccess =
1873 xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1874 if ( bSuccess )
1876 prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1878 xSourceKey->closeKey();
1880 xSourceKey = xReg->getRootKey();
1881 Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1882 mergeKeys( xDestKey, xSourceKey );
1883 xDestKey->closeKey();
1884 xSourceKey->closeKey();
1886 else
1888 throw CannotRegisterImplementationException(
1889 OUString( RTL_CONSTASCII_USTRINGPARAM( "ImplementationRegistration::doRegistration() component registration signaled failure" ) ),
1890 Reference< XInterface > () );
1893 // Cleanup Source registry.
1894 if ( xSourceKey->isValid() )
1895 xSourceKey->closeKey();
1897 catch(CannotRegisterImplementationException&)
1899 if ( xSourceKey->isValid() )
1900 xSourceKey->closeKey();
1901 // and throw again
1902 throw;
1909 Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1910 const Reference< XMultiComponentFactory > &rSMgr,
1911 const Reference < XComponentContext > & xCtx)
1914 Reference < XSimpleRegistry > xReg(
1915 rSMgr->createInstanceWithContext(
1916 spool().com_sun_star_registry_SimpleRegistry, xCtx ),
1917 UNO_QUERY);
1918 OSL_ASSERT( xReg.is() );
1919 return xReg;
1923 namespace stoc_bootstrap
1925 //*************************************************************************
1926 Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance(
1927 const Reference<XComponentContext> & xCtx ) // throw(Exception)
1929 return (XImplementationRegistration *)new stoc_impreg::ImplementationRegistration(xCtx);