1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: implreg.cxx,v $
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"
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>
45 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
46 #include <cppuhelper/implementationentry.hxx>
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)
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
;
86 #define IMPLNAME "com.sun.star.comp.stoc.ImplementationRegistration"
87 #define SERVICENAME "com.sun.star.registry.ImplementationRegistration"
92 OUString sImplementationName
;
93 OUString sServiceName
;
96 OUString slash_UNO_slash_REGISTRY_LINKS
;
97 OUString slash_IMPLEMENTATIONS
;
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
;
105 OUString com_sun_star_registry_SimpleRegistry
;
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") )
125 StringPool( const StringPool
& );
128 const StringPool
&spool()
130 static StringPool
*pPool
= 0;
133 MutexGuard
guard( Mutex::getGlobalMutex() );
136 static StringPool pool
;
144 extern rtl_StandardModuleCount g_moduleCount
;
146 namespace stoc_bootstrap
148 Sequence
< OUString
> impreg_getSupportedServiceNames()
150 static Sequence
< OUString
> *pNames
= 0;
153 MutexGuard
guard( Mutex::getGlobalMutex() );
156 static Sequence
< OUString
> seqNames(1);
157 seqNames
.getArray()[0] = stoc_impreg::spool().sServiceName
;
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();
191 OUString aLinkParent
;
192 Reference
< XRegistryKey
> xLinkParent
;
193 const sal_Unicode
* pTmpName
= NULL
;
194 const sal_Unicode
* pShortName
= NULL
;
197 for (sal_Int32 i
= 0; i
< linkNames
.getLength(); i
++)
199 aLinkName
= pLinkNames
[i
];
201 pTmpName
= aLinkName
.getStr();
203 if (pTmpName
[0] != L
'/')
206 sal_Int32 nIndex
= rtl_ustr_indexOfChar( pTmpName
, '%' );
210 pShortName
= pTmpName
+nIndex
;
212 while (pShortName
&& pShortName
[1] == L
'%')
214 nIndex
= rtl_ustr_indexOfChar( pShortName
+2, '%' );
218 pShortName
+= nIndex
+2;
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
);
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
, '%' );
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, '%' );
284 pShortName
+= nIndex
+2;
289 linkRefName
= linkRefName
+ link
.copy(pShortName
- pTmpName
+ 1);
290 linkName
= link
.copy(0, pShortName
- pTmpName
);
294 xSource
->createLink(linkName
, linkRefName
);
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
);
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
)
330 catch(InvalidRegistryException
&)
339 //*************************************************************************
340 // static searchLinkTargetForImpl
342 static OUString
searchLinkTargetForImpl(const Reference
< XRegistryKey
>& xRootKey
,
343 const OUString
& linkName
,
344 const OUString
& implName
)
345 // throw ( InvalidRegistryException, RuntimeException )
351 const StringPool
& pool
= spool();
352 Reference
< XRegistryKey
> xKey
= xRootKey
->openKey( pool
.slash_IMPLEMENTATIONS
);
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
);
376 // catch(InvalidRegistryException&)
383 //*************************************************************************
384 // static createUniqueSubEntry
386 static void createUniqueSubEntry(const Reference
< XRegistryKey
> & xSuperKey
,
387 const OUString
& value
)
388 // throw ( InvalidRegistryException, RuntimeException )
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
);
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
);
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
);
431 Sequence
<OUString
> implEntriesNew(1);
433 implEntriesNew
.getArray()[0] = value
;
435 xSuperKey
->setAsciiListValue(implEntriesNew
);
438 // catch(InvalidRegistryException&)
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
)
463 if (equals
== length
)
465 hasNoImplementations
= sal_True
;
468 Sequence
<OUString
> implEntriesNew(length
- equals
);
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
)
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
;
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
);
517 // catch (InvalidRegistryException&)
523 if (xRootKey
->isValid())
525 ret
= xRootKey
->createLink(linkName
, linkTarget
);
528 // catch(InvalidRegistryException&)
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
);
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
)
602 if (equals
== length
)
604 hasNoImplementations
= sal_True
;
609 if (length
> equals
+ 1)
611 Sequence
<OUString
> implEntriesNew(length
- equals
- 1);
614 sal_Bool first
= sal_True
;
615 for (sal_Int32 i
= 0; i
< length
; i
++)
617 if (implEntries
.getConstArray()[i
] != implName
)
621 oldImpl
= implEntries
.getConstArray()[i
];
625 implEntriesNew
.getArray()[j
++] = implEntries
.getConstArray()[i
];
630 xOldKey
->setAsciiListValue(implEntriesNew
);
633 oldImpl
= implEntries
.getConstArray()[0];
636 xRootKey
->deleteKey(xOldKey
->getKeyName());
639 OUString oldTarget
= searchLinkTargetForImpl(xRootKey
, linkName
, oldImpl
);
640 if (oldTarget
.getLength())
642 xRootKey
->createLink(linkName
, oldTarget
);
646 if (hasNoImplementations
)
649 hasNoImplementations
= sal_False
;
651 xRootKey
->deleteKey(xOldKey
->getKeyName());
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
,
675 // throw ( InvalidRegistryException, RuntimeException )
677 sal_Bool hasSubKeys
= sal_False
;
679 Sequence
<OUString
> keyNames
= xKey
->getKeyNames();
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
;
697 prepareUserLink(xDest
, linkName
, linkTarget
, implName
);
700 deleteUserLink(xDest
->getRootKey(), linkName
, linkTarget
, implName
);
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
);
720 OUString
keyName(xKey
->getKeyName().copy(xUnoKey
->getKeyName().getLength()));
722 Reference
< XRegistryKey
> xRootKey
= xDest
->getRootKey();
725 createUniqueSubEntry(xRootKey
->createKey(keyName
), implName
);
729 Reference
< XRegistryKey
> rKey
= xRootKey
->openKey(keyName
);
732 deleteSubEntry(rKey
, implName
);
733 xRootKey
->deleteKey(keyName
);
736 OUString path
= keyName
.copy(0, keyName
.lastIndexOf('/'));
737 if( path
.getLength() )
739 deletePathIfPossible(xRootKey
, path
);
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('/');
780 implName
= implName
.copy(firstDot
+ 1);
782 implNames
.push_back(implName
);
784 deleteAllLinkReferences(xReg
, xImplKey
);
786 xKey
= xImplKey
->openKey( pool
.slash_UNO
);
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
);
813 hasLocationUrl
= sal_False
;
814 xImplKey
->closeKey();
815 xReg
->getRootKey()->deleteKey(xImplKey
->getKeyName());
819 subKeys
= xSource
->openKeys();
820 if (subKeys
.getLength() == 0)
823 xReg
->getRootKey()->deleteKey(xSource
->getKeyName());
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 ];
874 if (nNewLength
!= nOrigRegLength
)
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 ) );
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
)
927 if (equals
== length
)
929 hasNoImplementations
= sal_True
;
934 Sequence
<OUString
> implEntriesNew(length
-equals
);
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)
962 xReg
->getRootKey()->deleteKey(xSource
->getKeyName());
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
))
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
] ))
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 )
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
;
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
1044 if (! is_supported_service( service_name
, xExistingService_td
))
1046 OUStringBuffer
buf( 64 );
1048 RTL_CONSTASCII_STRINGPARAM("existing singleton service (") );
1049 buf
.append( singleton_name
);
1050 buf
.append( (sal_Unicode
)'=' );
1051 buf
.append( existing_name
);
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
&)
1070 xKey2
->setStringValue( service_name
);
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())
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
] ))
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
);
1150 // update entries in SERVICES section
1151 Sequence
< Reference
< XRegistryKey
> > serviceKeys
= xKey
->openKeys();
1154 if (serviceKeys
.getLength())
1156 const Reference
< XRegistryKey
> * pServiceKeys
= serviceKeys
.getConstArray();
1158 implName
= OUString(xImplKey
->getKeyName().getStr() + 1);
1159 sal_Int32 firstDot
= implName
.indexOf('/');
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
),
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
);
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
);
1210 xKey
->setAsciiValue(locationUrl
);
1213 // update ACTIVATOR entry
1214 xKey
= xImplKey
->createKey( pool
.slash_UNO_slash_ACTIVATOR
);
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('.');
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
>
1299 ImplementationRegistration( const Reference
< XComponentContext
> & rSMgr
);
1300 ~ImplementationRegistration();
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
);
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
);
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() )
1380 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
1383 //*************************************************************************
1384 // ~ImplementationRegistration()
1386 ImplementationRegistration::~ImplementationRegistration()
1388 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
1393 OUString
ImplementationRegistration::getImplementationName() throw(RuntimeException
)
1395 return stoc_bootstrap::impreg_getImplementationName();
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
)
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
) {
1430 catch( UnknownPropertyException
& ) {
1431 // empty reference is error signal !
1439 //************************************************************************
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 ) {
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
> (),
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()) {
1468 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1469 "ImplementationRegistration::initialize() invalid first parameter,"
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
> (),
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() ) {
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
> (),
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() ) {
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
> (),
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
;
1515 rReg
= getRegistryFromServiceManager();
1518 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1519 "ImplementationRegistration::initialize() invalid fourth parameter,"
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
> (),
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
)
1546 implementationLoaderUrl
, locationUrl
, registeredLocationUrl
, xReg
);
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
);
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
);
1578 Reference
< XSimpleRegistry
> xRegistry
;
1582 // registry supplied by user
1587 xRegistry
= getRegistryFromServiceManager();
1590 if ( xRegistry
.is())
1592 doRegister(m_xSMgr
, m_xCtx
, xAct
, xRegistry
, implLoaderUrl
,
1593 locationUrl
, registeredLocationUrl
);
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
& )
1610 catch( InvalidRegistryException
& e
)
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
)
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
> () );
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
;
1671 Reference
< XPropertySet
> xPropSet
= Reference
< XPropertySet
>::query( m_xSMgr
);
1672 if( xPropSet
.is() ) {
1674 Any aAny
= xPropSet
->getPropertyValue( spool().Registry
);
1676 if( aAny
.getValueType().getTypeClass() == TypeClass_INTERFACE
)
1681 catch ( UnknownPropertyException
& ) {
1690 doRevoke(xRegistry
, location
);
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" );
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
);
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
);
1734 Reference
< XSimpleRegistry
> xReg
=
1735 createTemporarySimpleRegistry( m_xSMgr
, m_xCtx
);
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
;
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 )
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
);
1824 std::list
<OUString
>::const_iterator iter
= aNames
.begin();
1826 while (iter
!= aNames
.end())
1828 deleteAllServiceEntries(xDest
, xKey
, *iter
);
1833 xKey
= xRootKey
->openKey( OUSTR("/SINGLETONS") );
1834 if (xKey
.is() && xKey
->isValid())
1836 delete_all_singleton_entries( xKey
, aNames
);
1840 xRootKey
->closeKey();
1841 if (xKey
.is() && xKey
->isValid() )
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
);
1873 xAct
->writeRegistryInfo(xSourceKey
, implementationLoaderUrl
, locationUrl
);
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();
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();
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
),
1918 OSL_ASSERT( xReg
.is() );
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
);