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