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