1*647a425cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647a425cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647a425cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647a425cSAndrew Rist  * distributed with this work for additional information
6*647a425cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647a425cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647a425cSAndrew Rist  * "License"); you may not use this file except in compliance
9*647a425cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647a425cSAndrew Rist  *
11*647a425cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647a425cSAndrew Rist  *
13*647a425cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647a425cSAndrew Rist  * software distributed under the License is distributed on an
15*647a425cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647a425cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647a425cSAndrew Rist  * specific language governing permissions and limitations
18*647a425cSAndrew Rist  * under the License.
19*647a425cSAndrew Rist  *
20*647a425cSAndrew Rist  *************************************************************/
21*647a425cSAndrew Rist 
22*647a425cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_stoc.hxx"
26cdf0e10cSrcweir #include <stdlib.h>
27cdf0e10cSrcweir #include <string.h>
28cdf0e10cSrcweir #include <list>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <unistd.h>
31cdf0e10cSrcweir #include <cppuhelper/queryinterface.hxx>
32cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
33cdf0e10cSrcweir #include <cppuhelper/weak.hxx>
34cdf0e10cSrcweir #include <cppuhelper/servicefactory.hxx>
35cdf0e10cSrcweir #ifndef _CPPUHELPER_IMPLBASE3_HXX
36cdf0e10cSrcweir #include <cppuhelper/implbase3.hxx>
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
39cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx>
40cdf0e10cSrcweir #endif
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <uno/mapping.hxx>
43cdf0e10cSrcweir #include <osl/thread.h>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include <rtl/ustring.hxx>
46cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
47cdf0e10cSrcweir #include <rtl/strbuf.hxx>
48cdf0e10cSrcweir #include <osl/process.h>
49cdf0e10cSrcweir 
50cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
51cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
52cdf0e10cSrcweir #include <com/sun/star/loader/XImplementationLoader.hpp>
53cdf0e10cSrcweir #include <com/sun/star/registry/XImplementationRegistration2.hpp>
54cdf0e10cSrcweir #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
55cdf0e10cSrcweir #include <com/sun/star/reflection/XServiceTypeDescription.hpp>
56cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
57cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
58cdf0e10cSrcweir 
59cdf0e10cSrcweir #include "mergekeys.hxx"
60cdf0e10cSrcweir 
61cdf0e10cSrcweir #if defined(SAL_W32) || defined(SAL_OS2)
62cdf0e10cSrcweir #include <io.h>
63cdf0e10cSrcweir #endif
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 
68cdf0e10cSrcweir using namespace com::sun::star;
69cdf0e10cSrcweir using namespace com::sun::star::uno;
70cdf0e10cSrcweir using namespace com::sun::star::loader;
71cdf0e10cSrcweir using namespace com::sun::star::beans;
72cdf0e10cSrcweir using namespace com::sun::star::lang;
73cdf0e10cSrcweir using namespace com::sun::star::registry;
74cdf0e10cSrcweir using namespace cppu;
75cdf0e10cSrcweir using namespace rtl;
76cdf0e10cSrcweir using namespace osl;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir 
79cdf0e10cSrcweir #define IMPLNAME "com.sun.star.comp.stoc.ImplementationRegistration"
80cdf0e10cSrcweir #define SERVICENAME 		"com.sun.star.registry.ImplementationRegistration"
81cdf0e10cSrcweir namespace stoc_impreg
82cdf0e10cSrcweir {
83cdf0e10cSrcweir struct StringPool
84cdf0e10cSrcweir {
85cdf0e10cSrcweir     OUString sImplementationName;
86cdf0e10cSrcweir     OUString sServiceName;
87cdf0e10cSrcweir     OUString TMP;
88cdf0e10cSrcweir     OUString TEMP;
89cdf0e10cSrcweir     OUString slash_UNO_slash_REGISTRY_LINKS;
90cdf0e10cSrcweir     OUString slash_IMPLEMENTATIONS;
91cdf0e10cSrcweir     OUString slash_UNO;
92cdf0e10cSrcweir     OUString slash_UNO_slash_SERVICES;
93cdf0e10cSrcweir     OUString slash_UNO_slash_SINGLETONS;
94cdf0e10cSrcweir     OUString slash_SERVICES;
95cdf0e10cSrcweir     OUString slash_UNO_slash_LOCATION;
96cdf0e10cSrcweir     OUString slash_UNO_slash_ACTIVATOR;
97cdf0e10cSrcweir     OUString colon_old;
98cdf0e10cSrcweir     OUString com_sun_star_registry_SimpleRegistry;
99cdf0e10cSrcweir     OUString Registry;
StringPoolstoc_impreg::StringPool100cdf0e10cSrcweir     StringPool()
101cdf0e10cSrcweir         : sImplementationName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) )
102cdf0e10cSrcweir         , sServiceName( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) )
103cdf0e10cSrcweir         , TMP( RTL_CONSTASCII_USTRINGPARAM( "TMP" ) )
104cdf0e10cSrcweir         , TEMP( RTL_CONSTASCII_USTRINGPARAM( "TEMP" ) )
105cdf0e10cSrcweir         , slash_UNO_slash_REGISTRY_LINKS( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS"))
106cdf0e10cSrcweir         , slash_IMPLEMENTATIONS( RTL_CONSTASCII_USTRINGPARAM( "/IMPLEMENTATIONS" ) )
107cdf0e10cSrcweir         , slash_UNO( RTL_CONSTASCII_USTRINGPARAM("/UNO"))
108cdf0e10cSrcweir         , slash_UNO_slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES"))
109cdf0e10cSrcweir         , slash_UNO_slash_SINGLETONS( RTL_CONSTASCII_USTRINGPARAM("/UNO/SINGLETONS"))
110cdf0e10cSrcweir         , slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") )
111cdf0e10cSrcweir         , slash_UNO_slash_LOCATION( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") )
112cdf0e10cSrcweir         , slash_UNO_slash_ACTIVATOR( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") )
113cdf0e10cSrcweir         , colon_old( RTL_CONSTASCII_USTRINGPARAM(":old"))
114cdf0e10cSrcweir         , com_sun_star_registry_SimpleRegistry(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry") )
115cdf0e10cSrcweir         , Registry( RTL_CONSTASCII_USTRINGPARAM("Registry") )
116cdf0e10cSrcweir         {}
117cdf0e10cSrcweir private:
118cdf0e10cSrcweir     StringPool( const StringPool & );
119cdf0e10cSrcweir };
120cdf0e10cSrcweir 
spool()121cdf0e10cSrcweir const StringPool &spool()
122cdf0e10cSrcweir {
123cdf0e10cSrcweir     static StringPool *pPool = 0;
124cdf0e10cSrcweir     if( ! pPool )
125cdf0e10cSrcweir     {
126cdf0e10cSrcweir         MutexGuard guard( Mutex::getGlobalMutex() );
127cdf0e10cSrcweir         if( ! pPool )
128cdf0e10cSrcweir         {
129cdf0e10cSrcweir             static StringPool pool;
130cdf0e10cSrcweir             pPool = &pool;
131cdf0e10cSrcweir         }
132cdf0e10cSrcweir     }
133cdf0e10cSrcweir     return *pPool;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir extern rtl_StandardModuleCount g_moduleCount;
138cdf0e10cSrcweir 
139cdf0e10cSrcweir namespace stoc_bootstrap
140cdf0e10cSrcweir {
impreg_getSupportedServiceNames()141cdf0e10cSrcweir Sequence< OUString > impreg_getSupportedServiceNames()
142cdf0e10cSrcweir {
143cdf0e10cSrcweir 	static Sequence < OUString > *pNames = 0;
144cdf0e10cSrcweir 	if( ! pNames )
145cdf0e10cSrcweir 	{
146cdf0e10cSrcweir 		MutexGuard guard( Mutex::getGlobalMutex() );
147cdf0e10cSrcweir 		if( !pNames )
148cdf0e10cSrcweir 		{
149cdf0e10cSrcweir 			static Sequence< OUString > seqNames(1);
150cdf0e10cSrcweir 			seqNames.getArray()[0] = stoc_impreg::spool().sServiceName;
151cdf0e10cSrcweir 			pNames = &seqNames;
152cdf0e10cSrcweir 		}
153cdf0e10cSrcweir 	}
154cdf0e10cSrcweir 	return *pNames;
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
impreg_getImplementationName()157cdf0e10cSrcweir OUString impreg_getImplementationName()
158cdf0e10cSrcweir {
159cdf0e10cSrcweir     return stoc_impreg::spool().sImplementationName;
160cdf0e10cSrcweir }
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir namespace stoc_impreg
164cdf0e10cSrcweir {
165cdf0e10cSrcweir //*************************************************************************
166cdf0e10cSrcweir //	static deleteAllLinkReferences()
167cdf0e10cSrcweir //
deleteAllLinkReferences(const Reference<XSimpleRegistry> & xReg,const Reference<XRegistryKey> & xSource)168cdf0e10cSrcweir static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
169cdf0e10cSrcweir 									const Reference < XRegistryKey >& xSource)
170cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
171cdf0e10cSrcweir {
172cdf0e10cSrcweir     Reference < XRegistryKey > xKey = xSource->openKey(
173cdf0e10cSrcweir         spool().slash_UNO_slash_REGISTRY_LINKS );
174cdf0e10cSrcweir 
175cdf0e10cSrcweir     if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
176cdf0e10cSrcweir     {
177cdf0e10cSrcweir         Sequence<OUString> linkNames = xKey->getAsciiListValue();
178cdf0e10cSrcweir 
179cdf0e10cSrcweir         if (linkNames.getLength())
180cdf0e10cSrcweir         {
181cdf0e10cSrcweir             const OUString* pLinkNames = linkNames.getConstArray();
182cdf0e10cSrcweir 
183cdf0e10cSrcweir             OUString			aLinkName;
184cdf0e10cSrcweir             OUString			aLinkParent;
185cdf0e10cSrcweir             Reference < XRegistryKey >	xLinkParent;
186cdf0e10cSrcweir             const sal_Unicode*	pTmpName = NULL;
187cdf0e10cSrcweir             const sal_Unicode*	pShortName = NULL;
188cdf0e10cSrcweir             sal_Int32		   	sEnd = 0;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir             for (sal_Int32 i = 0; i < linkNames.getLength(); i++)
191cdf0e10cSrcweir             {
192cdf0e10cSrcweir                 aLinkName = pLinkNames[i];
193cdf0e10cSrcweir 
194cdf0e10cSrcweir                 pTmpName = aLinkName.getStr();
195cdf0e10cSrcweir 
196cdf0e10cSrcweir                 if (pTmpName[0] != L'/')
197cdf0e10cSrcweir                     continue;
198cdf0e10cSrcweir 
199cdf0e10cSrcweir                 sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
200cdf0e10cSrcweir                 if ( nIndex == -1 )
201cdf0e10cSrcweir                     pShortName = 0;
202cdf0e10cSrcweir                 else
203cdf0e10cSrcweir                     pShortName = pTmpName+nIndex;
204cdf0e10cSrcweir 
205cdf0e10cSrcweir                 while (pShortName && pShortName[1] == L'%')
206cdf0e10cSrcweir                 {
207cdf0e10cSrcweir                     nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
208cdf0e10cSrcweir                     if ( nIndex == -1 )
209cdf0e10cSrcweir                         pShortName = 0;
210cdf0e10cSrcweir                     else
211cdf0e10cSrcweir                         pShortName += nIndex+2;
212cdf0e10cSrcweir                 }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir                 if (pShortName)
215cdf0e10cSrcweir                 {
216cdf0e10cSrcweir                     aLinkName = aLinkName.copy(0, pShortName - pTmpName);
217cdf0e10cSrcweir                 }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir                 xReg->getRootKey()->deleteLink(aLinkName);
220cdf0e10cSrcweir 
221cdf0e10cSrcweir                 sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
222cdf0e10cSrcweir 
223cdf0e10cSrcweir                 aLinkParent = aLinkName.copy(0, sEnd);
224cdf0e10cSrcweir 
225cdf0e10cSrcweir                 while(aLinkParent.getLength())
226cdf0e10cSrcweir                 {
227cdf0e10cSrcweir                     xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
228cdf0e10cSrcweir 
229cdf0e10cSrcweir                     if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0))
230cdf0e10cSrcweir                     {
231cdf0e10cSrcweir                         aLinkName = aLinkParent;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir                         xReg->getRootKey()->deleteKey(aLinkParent);
234cdf0e10cSrcweir 
235cdf0e10cSrcweir                         sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
236cdf0e10cSrcweir 
237cdf0e10cSrcweir                         aLinkParent = aLinkName.copy(0, sEnd);
238cdf0e10cSrcweir                     } else
239cdf0e10cSrcweir                     {
240cdf0e10cSrcweir                         break;
241cdf0e10cSrcweir                     }
242cdf0e10cSrcweir                 }
243cdf0e10cSrcweir             }
244cdf0e10cSrcweir         }
245cdf0e10cSrcweir     }
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
248cdf0e10cSrcweir //*************************************************************************
249cdf0e10cSrcweir //	static prepareLink
250cdf0e10cSrcweir //
prepareLink(const Reference<XSimpleRegistry> & xDest,const Reference<XRegistryKey> & xSource,const OUString & link)251cdf0e10cSrcweir static void prepareLink( const Reference < XSimpleRegistry > & xDest,
252cdf0e10cSrcweir 						 const Reference < XRegistryKey > & xSource,
253cdf0e10cSrcweir 						 const OUString& link)
254cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir     OUString linkRefName = xSource->getKeyName();
257cdf0e10cSrcweir     OUString linkName(link);
258cdf0e10cSrcweir     sal_Bool	isRelativ = sal_False;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir     const sal_Unicode*	pTmpName = link.getStr();
261cdf0e10cSrcweir     const sal_Unicode*	pShortName;
262cdf0e10cSrcweir     sal_Int32           nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
263cdf0e10cSrcweir     if ( nIndex == -1 )
264cdf0e10cSrcweir         pShortName = 0;
265cdf0e10cSrcweir     else
266cdf0e10cSrcweir         pShortName = pTmpName+nIndex;
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     if (pTmpName[0] != L'/')
269cdf0e10cSrcweir         isRelativ = sal_True;
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     while (pShortName && pShortName[1] == L'%')
272cdf0e10cSrcweir     {
273cdf0e10cSrcweir         nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
274cdf0e10cSrcweir         if ( nIndex == -1 )
275cdf0e10cSrcweir             pShortName = 0;
276cdf0e10cSrcweir         else
277cdf0e10cSrcweir             pShortName += nIndex+2;
278cdf0e10cSrcweir     }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir     if (pShortName)
281cdf0e10cSrcweir     {
282cdf0e10cSrcweir         linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1);
283cdf0e10cSrcweir         linkName = link.copy(0, pShortName - pTmpName);
284cdf0e10cSrcweir     }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir     if (isRelativ)
287cdf0e10cSrcweir         xSource->createLink(linkName, linkRefName);
288cdf0e10cSrcweir     else
289cdf0e10cSrcweir         xDest->getRootKey()->createLink(linkName, linkRefName);
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir //*************************************************************************
293cdf0e10cSrcweir //	static searchImplForLink
294cdf0e10cSrcweir //
searchImplForLink(const Reference<XRegistryKey> & xRootKey,const OUString & linkName,const OUString & implName)295cdf0e10cSrcweir static OUString searchImplForLink(
296cdf0e10cSrcweir     const Reference < XRegistryKey > & xRootKey,
297cdf0e10cSrcweir     const OUString& linkName,
298cdf0e10cSrcweir     const OUString& implName )
299cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir     const StringPool & pool = spool();
302cdf0e10cSrcweir     Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
303cdf0e10cSrcweir     if (xKey.is())
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
306cdf0e10cSrcweir         const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
307cdf0e10cSrcweir         OUString key_name( pool.slash_UNO + linkName );
308cdf0e10cSrcweir 
309cdf0e10cSrcweir         for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
310cdf0e10cSrcweir         {
311cdf0e10cSrcweir             try
312cdf0e10cSrcweir             {
313cdf0e10cSrcweir                 Reference < XRegistryKey > xImplKey( pSubKeys[i] );
314cdf0e10cSrcweir                 if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
315cdf0e10cSrcweir                 {
316cdf0e10cSrcweir                     OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
317cdf0e10cSrcweir                     if (implName != oldImplName)
318cdf0e10cSrcweir                     {
319cdf0e10cSrcweir                         return oldImplName;
320cdf0e10cSrcweir                     }
321cdf0e10cSrcweir                 }
322cdf0e10cSrcweir             }
323cdf0e10cSrcweir             catch(InvalidRegistryException&)
324cdf0e10cSrcweir             {
325cdf0e10cSrcweir             }
326cdf0e10cSrcweir         }
327cdf0e10cSrcweir     }
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 	return OUString();
330cdf0e10cSrcweir }
331cdf0e10cSrcweir 
332cdf0e10cSrcweir //*************************************************************************
333cdf0e10cSrcweir //	static searchLinkTargetForImpl
334cdf0e10cSrcweir //
searchLinkTargetForImpl(const Reference<XRegistryKey> & xRootKey,const OUString & linkName,const OUString & implName)335cdf0e10cSrcweir static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
336cdf0e10cSrcweir                                         const OUString& linkName,
337cdf0e10cSrcweir                                         const OUString& implName)
338cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir 	OUString ret;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir //  	try
343cdf0e10cSrcweir //  	{
344cdf0e10cSrcweir         const StringPool & pool = spool();
345cdf0e10cSrcweir 		Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 		if (xKey.is())
348cdf0e10cSrcweir 		{
349cdf0e10cSrcweir 			Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 			const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
352cdf0e10cSrcweir 			Reference < XRegistryKey > xImplKey;
353cdf0e10cSrcweir 
354cdf0e10cSrcweir 			for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
355cdf0e10cSrcweir 			{
356cdf0e10cSrcweir 				xImplKey = pSubKeys[i];
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 				OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
359cdf0e10cSrcweir                 OUString qualifiedLinkName( pool.slash_UNO );
360cdf0e10cSrcweir                 qualifiedLinkName += linkName;
361cdf0e10cSrcweir 				if (tmpImplName == implName &&
362cdf0e10cSrcweir 					xImplKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK)
363cdf0e10cSrcweir 				{
364cdf0e10cSrcweir 					return xImplKey->getLinkTarget( qualifiedLinkName );
365cdf0e10cSrcweir 				}
366cdf0e10cSrcweir 			}
367cdf0e10cSrcweir 		}
368cdf0e10cSrcweir //  	}
369cdf0e10cSrcweir //  	catch(InvalidRegistryException&)
370cdf0e10cSrcweir //  	{
371cdf0e10cSrcweir //  	}
372cdf0e10cSrcweir 
373cdf0e10cSrcweir 	return ret;
374cdf0e10cSrcweir }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir //*************************************************************************
377cdf0e10cSrcweir //	static createUniqueSubEntry
378cdf0e10cSrcweir //
createUniqueSubEntry(const Reference<XRegistryKey> & xSuperKey,const OUString & value)379cdf0e10cSrcweir static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
380cdf0e10cSrcweir 								 const OUString& value)
381cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
382cdf0e10cSrcweir {
383cdf0e10cSrcweir 	if (xSuperKey.is())
384cdf0e10cSrcweir 	{
385cdf0e10cSrcweir //  		try
386cdf0e10cSrcweir //  		{
387cdf0e10cSrcweir         if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
388cdf0e10cSrcweir         {
389cdf0e10cSrcweir             sal_Int32 length = 0;
390cdf0e10cSrcweir             sal_Bool bReady = sal_False;
391cdf0e10cSrcweir 
392cdf0e10cSrcweir             Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
393cdf0e10cSrcweir             length = implEntries.getLength();
394cdf0e10cSrcweir 
395cdf0e10cSrcweir             for (sal_Int32 i = 0; !bReady && (i < length); i++)
396cdf0e10cSrcweir             {
397cdf0e10cSrcweir                 bReady = (implEntries.getConstArray()[i] == value);
398cdf0e10cSrcweir             }
399cdf0e10cSrcweir 
400cdf0e10cSrcweir             if (bReady)
401cdf0e10cSrcweir             {
402cdf0e10cSrcweir                 Sequence<OUString> implEntriesNew(length);
403cdf0e10cSrcweir                 implEntriesNew.getArray()[0] = value;
404cdf0e10cSrcweir 
405cdf0e10cSrcweir                 for (sal_Int32 i=0, j=1; i < length; i++)
406cdf0e10cSrcweir                 {
407cdf0e10cSrcweir                     if (implEntries.getConstArray()[i] != value)
408cdf0e10cSrcweir                         implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
409cdf0e10cSrcweir                 }
410cdf0e10cSrcweir                 xSuperKey->setAsciiListValue(implEntriesNew);
411cdf0e10cSrcweir             } else
412cdf0e10cSrcweir             {
413cdf0e10cSrcweir                 Sequence<OUString> implEntriesNew(length+1);
414cdf0e10cSrcweir                 implEntriesNew.getArray()[0] = value;
415cdf0e10cSrcweir 
416cdf0e10cSrcweir                 for (sal_Int32 i = 0; i < length; i++)
417cdf0e10cSrcweir                 {
418cdf0e10cSrcweir                     implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i];
419cdf0e10cSrcweir                 }
420cdf0e10cSrcweir                 xSuperKey->setAsciiListValue(implEntriesNew);
421cdf0e10cSrcweir             }
422cdf0e10cSrcweir         } else
423cdf0e10cSrcweir         {
424cdf0e10cSrcweir             Sequence<OUString> implEntriesNew(1);
425cdf0e10cSrcweir 
426cdf0e10cSrcweir             implEntriesNew.getArray()[0] = value;
427cdf0e10cSrcweir 
428cdf0e10cSrcweir             xSuperKey->setAsciiListValue(implEntriesNew);
429cdf0e10cSrcweir         }
430cdf0e10cSrcweir //  		}
431cdf0e10cSrcweir //  		catch(InvalidRegistryException&)
432cdf0e10cSrcweir //  		{
433cdf0e10cSrcweir //  		}
434cdf0e10cSrcweir 	}
435cdf0e10cSrcweir }
436cdf0e10cSrcweir 
437cdf0e10cSrcweir //*************************************************************************
438cdf0e10cSrcweir //	static deleteSubEntry
439cdf0e10cSrcweir //
deleteSubEntry(const Reference<XRegistryKey> & xSuperKey,const OUString & value)440cdf0e10cSrcweir static sal_Bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value)
441cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
442cdf0e10cSrcweir {
443cdf0e10cSrcweir     if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
444cdf0e10cSrcweir     {
445cdf0e10cSrcweir         Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
446cdf0e10cSrcweir         sal_Int32 length = implEntries.getLength();
447cdf0e10cSrcweir         sal_Int32 equals = 0;
448cdf0e10cSrcweir         sal_Bool hasNoImplementations = sal_False;
449cdf0e10cSrcweir 
450cdf0e10cSrcweir         for (sal_Int32 i = 0; i < length; i++)
451cdf0e10cSrcweir         {
452cdf0e10cSrcweir             if (implEntries.getConstArray()[i] == value)
453cdf0e10cSrcweir                 equals++;
454cdf0e10cSrcweir         }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir         if (equals == length)
457cdf0e10cSrcweir         {
458cdf0e10cSrcweir             hasNoImplementations = sal_True;
459cdf0e10cSrcweir         } else
460cdf0e10cSrcweir         {
461cdf0e10cSrcweir             Sequence<OUString> implEntriesNew(length - equals);
462cdf0e10cSrcweir 
463cdf0e10cSrcweir             sal_Int32 j = 0;
464cdf0e10cSrcweir             for (sal_Int32 i = 0; i < length; i++)
465cdf0e10cSrcweir             {
466cdf0e10cSrcweir                 if (implEntries.getConstArray()[i] != value)
467cdf0e10cSrcweir                 {
468cdf0e10cSrcweir                         implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
469cdf0e10cSrcweir                 }
470cdf0e10cSrcweir             }
471cdf0e10cSrcweir             xSuperKey->setAsciiListValue(implEntriesNew);
472cdf0e10cSrcweir         }
473cdf0e10cSrcweir 
474cdf0e10cSrcweir         if (hasNoImplementations)
475cdf0e10cSrcweir         {
476cdf0e10cSrcweir             return sal_True;
477cdf0e10cSrcweir         }
478cdf0e10cSrcweir     }
479cdf0e10cSrcweir 	return sal_False;
480cdf0e10cSrcweir }
481cdf0e10cSrcweir 
482cdf0e10cSrcweir //*************************************************************************
483cdf0e10cSrcweir //	static prepareUserLink
484cdf0e10cSrcweir //
prepareUserLink(const Reference<XSimpleRegistry> & xDest,const OUString & linkName,const OUString & linkTarget,const OUString & implName)485cdf0e10cSrcweir static void	prepareUserLink(const Reference < XSimpleRegistry >& xDest,
486cdf0e10cSrcweir                                 const OUString& linkName,
487cdf0e10cSrcweir                                 const OUString& linkTarget,
488cdf0e10cSrcweir                                 const OUString& implName)
489cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
490cdf0e10cSrcweir {
491cdf0e10cSrcweir 	sal_Bool ret = sal_False;
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 	Reference < XRegistryKey > xRootKey;
494cdf0e10cSrcweir 
495cdf0e10cSrcweir //  	try
496cdf0e10cSrcweir //  	{
497cdf0e10cSrcweir     xRootKey = xDest->getRootKey();
498cdf0e10cSrcweir 
499cdf0e10cSrcweir     if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
500cdf0e10cSrcweir     {
501cdf0e10cSrcweir         OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
502cdf0e10cSrcweir 
503cdf0e10cSrcweir         if (oldImplName.getLength())
504cdf0e10cSrcweir         {
505cdf0e10cSrcweir             createUniqueSubEntry(xDest->getRootKey()->createKey(
506cdf0e10cSrcweir                 linkName + spool().colon_old ), oldImplName);
507cdf0e10cSrcweir         }
508cdf0e10cSrcweir     }
509cdf0e10cSrcweir //  	}
510cdf0e10cSrcweir //  	catch (InvalidRegistryException&)
511cdf0e10cSrcweir //  	{
512cdf0e10cSrcweir //  	}
513cdf0e10cSrcweir 
514cdf0e10cSrcweir //  	try
515cdf0e10cSrcweir //  	{
516cdf0e10cSrcweir     if (xRootKey->isValid())
517cdf0e10cSrcweir     {
518cdf0e10cSrcweir         ret = xRootKey->createLink(linkName, linkTarget);
519cdf0e10cSrcweir     }
520cdf0e10cSrcweir //  	}
521cdf0e10cSrcweir //  	catch(InvalidRegistryException&)
522cdf0e10cSrcweir //  	{
523cdf0e10cSrcweir //  	}
524cdf0e10cSrcweir 
525cdf0e10cSrcweir //  	return ret;
526cdf0e10cSrcweir }
527cdf0e10cSrcweir 
528cdf0e10cSrcweir //*************************************************************************
529cdf0e10cSrcweir //	static deleteUserLink
530cdf0e10cSrcweir //
deletePathIfPossible(const Reference<XRegistryKey> & xRootKey,const OUString & path)531cdf0e10cSrcweir static void	deletePathIfPossible(const Reference < XRegistryKey >& xRootKey,
532cdf0e10cSrcweir 								 const OUString& path)
533cdf0e10cSrcweir {
534cdf0e10cSrcweir 	try
535cdf0e10cSrcweir 	{
536cdf0e10cSrcweir 		Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
537cdf0e10cSrcweir 
538cdf0e10cSrcweir 		if (keyNames.getLength() == 0 &&
539cdf0e10cSrcweir 			xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
540cdf0e10cSrcweir 		{
541cdf0e10cSrcweir 			xRootKey->deleteKey(path);
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 			OUString tmpPath(path);
544cdf0e10cSrcweir 			OUString newPath = tmpPath.copy(0, tmpPath.lastIndexOf('/'));
545cdf0e10cSrcweir 
546cdf0e10cSrcweir 			if (newPath.getLength() > 1)
547cdf0e10cSrcweir 				deletePathIfPossible(xRootKey, newPath);
548cdf0e10cSrcweir 		}
549cdf0e10cSrcweir 	}
550cdf0e10cSrcweir 	catch(InvalidRegistryException&)
551cdf0e10cSrcweir 	{
552cdf0e10cSrcweir 	}
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 
556cdf0e10cSrcweir //*************************************************************************
557cdf0e10cSrcweir //	static deleteUserLink
558cdf0e10cSrcweir //
deleteUserLink(const Reference<XRegistryKey> & xRootKey,const OUString & linkName,const OUString & linkTarget,const OUString & implName)559cdf0e10cSrcweir static void	deleteUserLink(const Reference < XRegistryKey >& xRootKey,
560cdf0e10cSrcweir                                const OUString& linkName,
561cdf0e10cSrcweir                                const OUString& linkTarget,
562cdf0e10cSrcweir                                const OUString& implName)
563cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir     sal_Bool bClean = sal_False;
566cdf0e10cSrcweir 
567cdf0e10cSrcweir     if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
568cdf0e10cSrcweir     {
569cdf0e10cSrcweir         OUString tmpTarget = xRootKey->getLinkTarget(linkName);
570cdf0e10cSrcweir 
571cdf0e10cSrcweir         if (tmpTarget == linkTarget)
572cdf0e10cSrcweir         {
573cdf0e10cSrcweir             xRootKey->deleteLink(linkName);
574cdf0e10cSrcweir         }
575cdf0e10cSrcweir     }
576cdf0e10cSrcweir 
577cdf0e10cSrcweir     Reference < XRegistryKey > xOldKey = xRootKey->openKey(
578cdf0e10cSrcweir         linkName + spool().colon_old );
579cdf0e10cSrcweir     if (xOldKey.is())
580cdf0e10cSrcweir     {
581cdf0e10cSrcweir         sal_Bool hasNoImplementations = sal_False;
582cdf0e10cSrcweir 
583cdf0e10cSrcweir         if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
584cdf0e10cSrcweir         {
585cdf0e10cSrcweir             Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
586cdf0e10cSrcweir             sal_Int32 length = implEntries.getLength();
587cdf0e10cSrcweir             sal_Int32 equals = 0;
588cdf0e10cSrcweir 
589cdf0e10cSrcweir             for (sal_Int32 i = 0; i < length; i++)
590cdf0e10cSrcweir             {
591cdf0e10cSrcweir                 if (implEntries.getConstArray()[i] == implName)
592cdf0e10cSrcweir                     equals++;
593cdf0e10cSrcweir             }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir             if (equals == length)
596cdf0e10cSrcweir             {
597cdf0e10cSrcweir                 hasNoImplementations = sal_True;
598cdf0e10cSrcweir             } else
599cdf0e10cSrcweir             {
600cdf0e10cSrcweir                 OUString oldImpl;
601cdf0e10cSrcweir 
602cdf0e10cSrcweir                 if (length > equals + 1)
603cdf0e10cSrcweir                 {
604cdf0e10cSrcweir                     Sequence<OUString> implEntriesNew(length - equals - 1);
605cdf0e10cSrcweir 
606cdf0e10cSrcweir                     sal_Int32 j = 0;
607cdf0e10cSrcweir                     sal_Bool first = sal_True;
608cdf0e10cSrcweir                     for (sal_Int32 i = 0; i < length; i++)
609cdf0e10cSrcweir                     {
610cdf0e10cSrcweir                         if (implEntries.getConstArray()[i] != implName)
611cdf0e10cSrcweir                         {
612cdf0e10cSrcweir                             if (first)
613cdf0e10cSrcweir                             {
614cdf0e10cSrcweir                                 oldImpl = implEntries.getConstArray()[i];
615cdf0e10cSrcweir                                 first = sal_False;
616cdf0e10cSrcweir                             } else
617cdf0e10cSrcweir                             {
618cdf0e10cSrcweir                                 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
619cdf0e10cSrcweir                             }
620cdf0e10cSrcweir                         }
621cdf0e10cSrcweir                     }
622cdf0e10cSrcweir 
623cdf0e10cSrcweir                     xOldKey->setAsciiListValue(implEntriesNew);
624cdf0e10cSrcweir                 } else
625cdf0e10cSrcweir                 {
626cdf0e10cSrcweir                     oldImpl = implEntries.getConstArray()[0];
627cdf0e10cSrcweir                     rtl::OUString path(xOldKey->getKeyName());
628cdf0e10cSrcweir                     xOldKey->closeKey();
629cdf0e10cSrcweir                     xRootKey->deleteKey(path);
630cdf0e10cSrcweir                 }
631cdf0e10cSrcweir 
632cdf0e10cSrcweir                 OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
633cdf0e10cSrcweir                 if (oldTarget.getLength())
634cdf0e10cSrcweir                 {
635cdf0e10cSrcweir                     xRootKey->createLink(linkName, oldTarget);
636cdf0e10cSrcweir                 }
637cdf0e10cSrcweir             }
638cdf0e10cSrcweir 
639cdf0e10cSrcweir             if (hasNoImplementations)
640cdf0e10cSrcweir             {
641cdf0e10cSrcweir                 bClean = sal_True;
642cdf0e10cSrcweir                 hasNoImplementations = sal_False;
643cdf0e10cSrcweir                 rtl::OUString path(xOldKey->getKeyName());
644cdf0e10cSrcweir                 xOldKey->closeKey();
645cdf0e10cSrcweir                 xRootKey->deleteKey(path);
646cdf0e10cSrcweir             }
647cdf0e10cSrcweir         }
648cdf0e10cSrcweir     } else
649cdf0e10cSrcweir     {
650cdf0e10cSrcweir         bClean = sal_True;
651cdf0e10cSrcweir     }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir     if (bClean)
654cdf0e10cSrcweir     {
655cdf0e10cSrcweir         OUString tmpName(linkName);
656cdf0e10cSrcweir         OUString path = tmpName.copy(0, tmpName.lastIndexOf('/'));
657cdf0e10cSrcweir         deletePathIfPossible(xRootKey, path);
658cdf0e10cSrcweir     }
659cdf0e10cSrcweir }
660cdf0e10cSrcweir 
661cdf0e10cSrcweir //*************************************************************************
662cdf0e10cSrcweir //	static prepareUserKeys
663cdf0e10cSrcweir //
prepareUserKeys(const Reference<XSimpleRegistry> & xDest,const Reference<XRegistryKey> & xUnoKey,const Reference<XRegistryKey> & xKey,const OUString & implName,sal_Bool bRegister)664cdf0e10cSrcweir static void	prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
665cdf0e10cSrcweir                                 const Reference < XRegistryKey >& xUnoKey,
666cdf0e10cSrcweir                                 const Reference < XRegistryKey >& xKey,
667cdf0e10cSrcweir                                 const OUString& implName,
668cdf0e10cSrcweir                                 sal_Bool bRegister)
669cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
670cdf0e10cSrcweir {
671cdf0e10cSrcweir 	sal_Bool hasSubKeys = sal_False;
672cdf0e10cSrcweir 
673cdf0e10cSrcweir     Sequence<OUString> keyNames = xKey->getKeyNames();
674cdf0e10cSrcweir 
675cdf0e10cSrcweir     OUString relativKey;
676cdf0e10cSrcweir     if (keyNames.getLength())
677cdf0e10cSrcweir         relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
678cdf0e10cSrcweir 
679cdf0e10cSrcweir     if (keyNames.getLength() == 1 &&
680cdf0e10cSrcweir         xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
681cdf0e10cSrcweir     {
682cdf0e10cSrcweir         hasSubKeys = sal_True;
683cdf0e10cSrcweir 
684cdf0e10cSrcweir         OUString linkTarget = xKey->getLinkTarget(relativKey);
685cdf0e10cSrcweir         OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
686cdf0e10cSrcweir 
687cdf0e10cSrcweir         linkName = linkName + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + relativKey;
688cdf0e10cSrcweir 
689cdf0e10cSrcweir         if (bRegister)
690cdf0e10cSrcweir         {
691cdf0e10cSrcweir             prepareUserLink(xDest, linkName, linkTarget, implName);
692cdf0e10cSrcweir         } else
693cdf0e10cSrcweir         {
694cdf0e10cSrcweir             deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
695cdf0e10cSrcweir         }
696cdf0e10cSrcweir     } else
697cdf0e10cSrcweir     {
698cdf0e10cSrcweir         Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
699cdf0e10cSrcweir 
700cdf0e10cSrcweir         if (subKeys.getLength())
701cdf0e10cSrcweir         {
702cdf0e10cSrcweir             hasSubKeys = sal_True;
703cdf0e10cSrcweir             const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
704cdf0e10cSrcweir 
705cdf0e10cSrcweir             for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
706cdf0e10cSrcweir             {
707cdf0e10cSrcweir                 prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
708cdf0e10cSrcweir             }
709cdf0e10cSrcweir         }
710cdf0e10cSrcweir     }
711cdf0e10cSrcweir 
712cdf0e10cSrcweir     if (! hasSubKeys)
713cdf0e10cSrcweir     {
714cdf0e10cSrcweir         OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
715cdf0e10cSrcweir 
716cdf0e10cSrcweir         Reference < XRegistryKey > xRootKey = xDest->getRootKey();
717cdf0e10cSrcweir         if (bRegister)
718cdf0e10cSrcweir         {
719cdf0e10cSrcweir             createUniqueSubEntry(xRootKey->createKey(keyName), implName);
720cdf0e10cSrcweir         }
721cdf0e10cSrcweir         else
722cdf0e10cSrcweir         {
723cdf0e10cSrcweir             Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
724cdf0e10cSrcweir             if( rKey.is() )
725cdf0e10cSrcweir             {
726cdf0e10cSrcweir                 deleteSubEntry(rKey, implName);
727cdf0e10cSrcweir                 xRootKey->deleteKey(keyName);
728cdf0e10cSrcweir             }
729cdf0e10cSrcweir 
730cdf0e10cSrcweir             OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
731cdf0e10cSrcweir             if( path.getLength() )
732cdf0e10cSrcweir             {
733cdf0e10cSrcweir                 deletePathIfPossible(xRootKey, path);
734cdf0e10cSrcweir             }
735cdf0e10cSrcweir         }
736cdf0e10cSrcweir     }
737cdf0e10cSrcweir 	return;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir 
740cdf0e10cSrcweir //*************************************************************************
741cdf0e10cSrcweir //	static deleteAllImplementations
742cdf0e10cSrcweir //
deleteAllImplementations(const Reference<XSimpleRegistry> & xReg,const Reference<XRegistryKey> & xSource,const OUString & locationUrl,std::list<OUString> & implNames)743cdf0e10cSrcweir static void deleteAllImplementations(	const Reference < XSimpleRegistry >& xReg,
744cdf0e10cSrcweir 										const Reference < XRegistryKey >& xSource,
745cdf0e10cSrcweir 										const OUString& locationUrl,
746cdf0e10cSrcweir 										std::list<OUString> & implNames)
747cdf0e10cSrcweir     // throw (InvalidRegistryException, RuntimeException)
748cdf0e10cSrcweir {
749cdf0e10cSrcweir     Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
750cdf0e10cSrcweir 
751cdf0e10cSrcweir     if (subKeys.getLength() > 0)
752cdf0e10cSrcweir     {
753cdf0e10cSrcweir         const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
754cdf0e10cSrcweir         Reference < XRegistryKey > xImplKey;
755cdf0e10cSrcweir         sal_Bool hasLocationUrl = sal_False;
756cdf0e10cSrcweir 
757cdf0e10cSrcweir         const StringPool &pool = spool();
758cdf0e10cSrcweir         for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
759cdf0e10cSrcweir         {
760cdf0e10cSrcweir             xImplKey = pSubKeys[i];
761cdf0e10cSrcweir             Reference < XRegistryKey > xKey = xImplKey->openKey(
762cdf0e10cSrcweir                 pool.slash_UNO_slash_LOCATION );
763cdf0e10cSrcweir 
764cdf0e10cSrcweir             if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
765cdf0e10cSrcweir             {
766cdf0e10cSrcweir                 if (xKey->getAsciiValue() == locationUrl)
767cdf0e10cSrcweir                 {
768cdf0e10cSrcweir                     hasLocationUrl = sal_True;
769cdf0e10cSrcweir 
770cdf0e10cSrcweir                     OUString implName(xImplKey->getKeyName().getStr() + 1);
771cdf0e10cSrcweir                     sal_Int32 firstDot = implName.indexOf('/');
772cdf0e10cSrcweir 
773cdf0e10cSrcweir                     if (firstDot >= 0)
774cdf0e10cSrcweir                         implName = implName.copy(firstDot + 1);
775cdf0e10cSrcweir 
776cdf0e10cSrcweir                     implNames.push_back(implName);
777cdf0e10cSrcweir 
778cdf0e10cSrcweir                     deleteAllLinkReferences(xReg, xImplKey);
779cdf0e10cSrcweir 
780cdf0e10cSrcweir                     xKey = xImplKey->openKey( pool.slash_UNO );
781cdf0e10cSrcweir                     if (xKey.is())
782cdf0e10cSrcweir                     {
783cdf0e10cSrcweir                         Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
784cdf0e10cSrcweir 
785cdf0e10cSrcweir                         if (subKeys2.getLength())
786cdf0e10cSrcweir                         {
787cdf0e10cSrcweir                             const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
788cdf0e10cSrcweir 
789cdf0e10cSrcweir                             for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
790cdf0e10cSrcweir                             {
791cdf0e10cSrcweir                                 if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
792cdf0e10cSrcweir                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
793cdf0e10cSrcweir                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
794cdf0e10cSrcweir                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
795cdf0e10cSrcweir                                     pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
796cdf0e10cSrcweir                                 {
797cdf0e10cSrcweir                                     prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, sal_False);
798cdf0e10cSrcweir                                 }
799cdf0e10cSrcweir                             }
800cdf0e10cSrcweir                         }
801cdf0e10cSrcweir                     }
802cdf0e10cSrcweir                 }
803cdf0e10cSrcweir             }
804cdf0e10cSrcweir 
805cdf0e10cSrcweir             if (hasLocationUrl)
806cdf0e10cSrcweir             {
807cdf0e10cSrcweir                 hasLocationUrl = sal_False;
808cdf0e10cSrcweir                 rtl::OUString path(xImplKey->getKeyName());
809cdf0e10cSrcweir                 xImplKey->closeKey();
810cdf0e10cSrcweir                 xReg->getRootKey()->deleteKey(path);
811cdf0e10cSrcweir             }
812cdf0e10cSrcweir         }
813cdf0e10cSrcweir 
814cdf0e10cSrcweir         subKeys = xSource->openKeys();
815cdf0e10cSrcweir         if (subKeys.getLength() == 0)
816cdf0e10cSrcweir         {
817cdf0e10cSrcweir             rtl::OUString path(xSource->getKeyName());
818cdf0e10cSrcweir             xSource->closeKey();
819cdf0e10cSrcweir             xReg->getRootKey()->deleteKey(path);
820cdf0e10cSrcweir         }
821cdf0e10cSrcweir     } else
822cdf0e10cSrcweir     {
823cdf0e10cSrcweir         rtl::OUString path(xSource->getKeyName());
824cdf0e10cSrcweir         xSource->closeKey();
825cdf0e10cSrcweir         xReg->getRootKey()->deleteKey(path);
826cdf0e10cSrcweir     }
827cdf0e10cSrcweir }
828cdf0e10cSrcweir 
829cdf0e10cSrcweir //==================================================================================================
delete_all_singleton_entries(Reference<registry::XRegistryKey> const & xSingletons_section,::std::list<OUString> const & impl_names)830cdf0e10cSrcweir static void delete_all_singleton_entries(
831cdf0e10cSrcweir 	Reference < registry::XRegistryKey > const & xSingletons_section,
832cdf0e10cSrcweir     ::std::list< OUString > const & impl_names )
833cdf0e10cSrcweir     // throw (InvalidRegistryException, RuntimeException)
834cdf0e10cSrcweir {
835cdf0e10cSrcweir     Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
836cdf0e10cSrcweir     Reference< registry::XRegistryKey > const * subkeys = singletons.getConstArray();
837cdf0e10cSrcweir     for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
838cdf0e10cSrcweir     {
839cdf0e10cSrcweir         Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
840cdf0e10cSrcweir         Reference< registry::XRegistryKey > xRegisteredImplNames(
841cdf0e10cSrcweir             xSingleton->openKey( OUSTR("REGISTERED_BY") ) );
842cdf0e10cSrcweir         if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
843cdf0e10cSrcweir         {
844cdf0e10cSrcweir             Sequence< OUString > registered_implnames;
845cdf0e10cSrcweir             try
846cdf0e10cSrcweir             {
847cdf0e10cSrcweir                 registered_implnames = xRegisteredImplNames->getAsciiListValue();
848cdf0e10cSrcweir             }
849cdf0e10cSrcweir             catch (registry::InvalidValueException &)
850cdf0e10cSrcweir             {
851cdf0e10cSrcweir             }
852cdf0e10cSrcweir             OUString const * p = registered_implnames.getConstArray();
853cdf0e10cSrcweir             sal_Int32 nOrigRegLength = registered_implnames.getLength();
854cdf0e10cSrcweir             sal_Int32 nNewLength = nOrigRegLength;
855cdf0e10cSrcweir             for ( sal_Int32 n = nOrigRegLength; n--; )
856cdf0e10cSrcweir             {
857cdf0e10cSrcweir                 OUString const & registered_implname = p[ n ];
858cdf0e10cSrcweir 
859cdf0e10cSrcweir                 ::std::list< OUString >::const_iterator iPos( impl_names.begin() );
860cdf0e10cSrcweir                 ::std::list< OUString >::const_iterator const iEnd( impl_names.end() );
861cdf0e10cSrcweir                 for ( ; iPos != iEnd; ++iPos )
862cdf0e10cSrcweir                 {
863cdf0e10cSrcweir                     if (iPos->equals( registered_implname ))
864cdf0e10cSrcweir                     {
865cdf0e10cSrcweir                         registered_implnames[ n ] = p[ nNewLength -1 ];
866cdf0e10cSrcweir                         --nNewLength;
867cdf0e10cSrcweir                     }
868cdf0e10cSrcweir                 }
869cdf0e10cSrcweir             }
870cdf0e10cSrcweir 
871cdf0e10cSrcweir             if (nNewLength != nOrigRegLength)
872cdf0e10cSrcweir             {
873cdf0e10cSrcweir                 if (0 == nNewLength)
874cdf0e10cSrcweir                 {
875cdf0e10cSrcweir                     // remove whole entry
876cdf0e10cSrcweir                     xRegisteredImplNames->closeKey();
877cdf0e10cSrcweir                     xSingleton->deleteKey( OUSTR("REGISTERED_BY") );
878cdf0e10cSrcweir                     // registry key cannot provide its relative name, only absolute :(
879cdf0e10cSrcweir                     OUString abs( xSingleton->getKeyName() );
880cdf0e10cSrcweir                     xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
881cdf0e10cSrcweir                 }
882cdf0e10cSrcweir                 else
883cdf0e10cSrcweir                 {
884cdf0e10cSrcweir                     registered_implnames.realloc( nNewLength );
885cdf0e10cSrcweir                     xRegisteredImplNames->setAsciiListValue( registered_implnames );
886cdf0e10cSrcweir                 }
887cdf0e10cSrcweir             }
888cdf0e10cSrcweir         }
889cdf0e10cSrcweir     }
890cdf0e10cSrcweir }
891cdf0e10cSrcweir 
892cdf0e10cSrcweir //*************************************************************************
893cdf0e10cSrcweir //	static deleteAllServiceEntries
894cdf0e10cSrcweir //
deleteAllServiceEntries(const Reference<XSimpleRegistry> & xReg,const Reference<XRegistryKey> & xSource,const OUString & implName)895cdf0e10cSrcweir static void deleteAllServiceEntries(	const Reference < XSimpleRegistry >& xReg,
896cdf0e10cSrcweir 										const Reference < XRegistryKey >& xSource,
897cdf0e10cSrcweir 										const OUString& implName)
898cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
899cdf0e10cSrcweir {
900cdf0e10cSrcweir     Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
901cdf0e10cSrcweir 
902cdf0e10cSrcweir     if (subKeys.getLength() > 0)
903cdf0e10cSrcweir     {
904cdf0e10cSrcweir         const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
905cdf0e10cSrcweir         Reference < XRegistryKey > xServiceKey;
906cdf0e10cSrcweir         sal_Bool hasNoImplementations = sal_False;
907cdf0e10cSrcweir 
908cdf0e10cSrcweir         for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
909cdf0e10cSrcweir         {
910cdf0e10cSrcweir             xServiceKey = pSubKeys[i];
911cdf0e10cSrcweir 
912cdf0e10cSrcweir             if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
913cdf0e10cSrcweir             {
914cdf0e10cSrcweir                 Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
915cdf0e10cSrcweir                 sal_Int32 length = implEntries.getLength();
916cdf0e10cSrcweir                 sal_Int32 equals = 0;
917cdf0e10cSrcweir 
918cdf0e10cSrcweir                 for (sal_Int32 j = 0; j < length; j++)
919cdf0e10cSrcweir                 {
920cdf0e10cSrcweir                     if (implEntries.getConstArray()[j] == implName)
921cdf0e10cSrcweir                         equals++;
922cdf0e10cSrcweir                 }
923cdf0e10cSrcweir 
924cdf0e10cSrcweir                 if (equals == length)
925cdf0e10cSrcweir                 {
926cdf0e10cSrcweir                     hasNoImplementations = sal_True;
927cdf0e10cSrcweir                 } else
928cdf0e10cSrcweir                 {
929cdf0e10cSrcweir                     if (equals > 0)
930cdf0e10cSrcweir                     {
931cdf0e10cSrcweir                         Sequence<OUString> implEntriesNew(length-equals);
932cdf0e10cSrcweir 
933cdf0e10cSrcweir                         sal_Int32 j = 0;
934cdf0e10cSrcweir                         for (sal_Int32 k = 0; k < length; k++)
935cdf0e10cSrcweir                         {
936cdf0e10cSrcweir                             if (implEntries.getConstArray()[k] != implName)
937cdf0e10cSrcweir                             {
938cdf0e10cSrcweir                                 implEntriesNew.getArray()[j++] = implEntries.getConstArray()[k];
939cdf0e10cSrcweir                             }
940cdf0e10cSrcweir                         }
941cdf0e10cSrcweir 
942cdf0e10cSrcweir                         xServiceKey->setAsciiListValue(implEntriesNew);
943cdf0e10cSrcweir                     }
944cdf0e10cSrcweir                 }
945cdf0e10cSrcweir             }
946cdf0e10cSrcweir 
947cdf0e10cSrcweir             if (hasNoImplementations)
948cdf0e10cSrcweir             {
949cdf0e10cSrcweir                 hasNoImplementations = sal_False;
950cdf0e10cSrcweir                 rtl::OUString path(xServiceKey->getKeyName());
951cdf0e10cSrcweir                 xServiceKey->closeKey();
952cdf0e10cSrcweir                 xReg->getRootKey()->deleteKey(path);
953cdf0e10cSrcweir             }
954cdf0e10cSrcweir         }
955cdf0e10cSrcweir 
956cdf0e10cSrcweir         subKeys = xSource->openKeys();
957cdf0e10cSrcweir         if (subKeys.getLength() == 0)
958cdf0e10cSrcweir         {
959cdf0e10cSrcweir             rtl::OUString path(xSource->getKeyName());
960cdf0e10cSrcweir             xSource->closeKey();
961cdf0e10cSrcweir             xReg->getRootKey()->deleteKey(path);
962cdf0e10cSrcweir         }
963cdf0e10cSrcweir     } else
964cdf0e10cSrcweir     {
965cdf0e10cSrcweir         rtl::OUString path(xSource->getKeyName());
966cdf0e10cSrcweir         xSource->closeKey();
967cdf0e10cSrcweir         xReg->getRootKey()->deleteKey(path);
968cdf0e10cSrcweir     }
969cdf0e10cSrcweir }
970cdf0e10cSrcweir 
971cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
is_supported_service(OUString const & service_name,Reference<reflection::XServiceTypeDescription> const & xService_td)972cdf0e10cSrcweir static bool is_supported_service(
973cdf0e10cSrcweir     OUString const & service_name,
974cdf0e10cSrcweir     Reference< reflection::XServiceTypeDescription > const & xService_td )
975cdf0e10cSrcweir {
976cdf0e10cSrcweir     if (xService_td->getName().equals( service_name ))
977cdf0e10cSrcweir         return true;
978cdf0e10cSrcweir     Sequence< Reference< reflection::XServiceTypeDescription > > seq(
979cdf0e10cSrcweir         xService_td->getMandatoryServices() );
980cdf0e10cSrcweir     Reference< reflection::XServiceTypeDescription > const * p = seq.getConstArray();
981cdf0e10cSrcweir     for ( sal_Int32 nPos = seq.getLength(); nPos--; )
982cdf0e10cSrcweir     {
983cdf0e10cSrcweir         if (is_supported_service( service_name, p[ nPos ] ))
984cdf0e10cSrcweir             return true;
985cdf0e10cSrcweir     }
986cdf0e10cSrcweir     return false;
987cdf0e10cSrcweir }
988cdf0e10cSrcweir 
989cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
insert_singletons(Reference<registry::XSimpleRegistry> const & xDest,Reference<registry::XRegistryKey> const & xImplKey,Reference<XComponentContext> const & xContext)990cdf0e10cSrcweir static void insert_singletons(
991cdf0e10cSrcweir     Reference< registry::XSimpleRegistry > const & xDest,
992cdf0e10cSrcweir     Reference< registry::XRegistryKey > const & xImplKey,
993cdf0e10cSrcweir     Reference< XComponentContext > const & xContext )
994cdf0e10cSrcweir     // throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
995cdf0e10cSrcweir {
996cdf0e10cSrcweir     // singletons
997cdf0e10cSrcweir     Reference< registry::XRegistryKey > xKey( xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
998cdf0e10cSrcweir     if (xKey.is() && xKey->isValid())
999cdf0e10cSrcweir     {
1000cdf0e10cSrcweir         OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
1001cdf0e10cSrcweir         // singleton entries
1002cdf0e10cSrcweir         Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
1003cdf0e10cSrcweir         Reference< registry::XRegistryKey > const * p = xSingletons_section.getConstArray();
1004cdf0e10cSrcweir         for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
1005cdf0e10cSrcweir         {
1006cdf0e10cSrcweir             Reference< registry::XRegistryKey > const & xSingleton = p[ nPos ];
1007cdf0e10cSrcweir             OUString singleton_name(
1008cdf0e10cSrcweir                 xSingleton->getKeyName().copy(
1009cdf0e10cSrcweir                     implname.getLength() + sizeof ("/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
1010cdf0e10cSrcweir             OUString service_name( xSingleton->getStringValue() );
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir             OUString keyname( OUSTR("/SINGLETONS/") + singleton_name );
1013cdf0e10cSrcweir             Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
1014cdf0e10cSrcweir             if (xKey2.is() && xKey2->isValid())
1015cdf0e10cSrcweir             {
1016cdf0e10cSrcweir                 try
1017cdf0e10cSrcweir                 {
1018cdf0e10cSrcweir                     OUString existing_name( xKey2->getStringValue() );
1019cdf0e10cSrcweir                     if (! existing_name.equals( service_name ))
1020cdf0e10cSrcweir                     {
1021cdf0e10cSrcweir                         Reference< container::XHierarchicalNameAccess > xTDMgr;
1022cdf0e10cSrcweir                         OUString the_tdmgr =
1023cdf0e10cSrcweir                             OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
1024cdf0e10cSrcweir                         xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
1025cdf0e10cSrcweir                         if (! xTDMgr.is())
1026cdf0e10cSrcweir                         {
1027cdf0e10cSrcweir                             throw RuntimeException(
1028cdf0e10cSrcweir                                 OUSTR("cannot get singleton ") + the_tdmgr,
1029cdf0e10cSrcweir                                 Reference< XInterface >() );
1030cdf0e10cSrcweir                         }
1031cdf0e10cSrcweir                         try
1032cdf0e10cSrcweir                         {
1033cdf0e10cSrcweir                             Reference< reflection::XServiceTypeDescription > xExistingService_td;
1034cdf0e10cSrcweir                             xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
1035cdf0e10cSrcweir                             if (! xExistingService_td.is())
1036cdf0e10cSrcweir                             {
1037cdf0e10cSrcweir                                 throw RuntimeException(
1038cdf0e10cSrcweir                                     OUSTR("cannot get service type description: ") + existing_name,
1039cdf0e10cSrcweir                                     Reference< XInterface >() );
1040cdf0e10cSrcweir                             }
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir                             // everything's fine if existing service entry supports the one
1043cdf0e10cSrcweir                             // to be registered
1044cdf0e10cSrcweir                             if (! is_supported_service( service_name, xExistingService_td ))
1045cdf0e10cSrcweir                             {
1046cdf0e10cSrcweir                                 OUStringBuffer buf( 64 );
1047cdf0e10cSrcweir                                 buf.appendAscii(
1048cdf0e10cSrcweir                                     RTL_CONSTASCII_STRINGPARAM("existing singleton service (") );
1049cdf0e10cSrcweir                                 buf.append( singleton_name );
1050cdf0e10cSrcweir                                 buf.append( (sal_Unicode)'=' );
1051cdf0e10cSrcweir                                 buf.append( existing_name );
1052cdf0e10cSrcweir                                 buf.appendAscii(
1053cdf0e10cSrcweir                                     RTL_CONSTASCII_STRINGPARAM(") does not support given one: ") );
1054cdf0e10cSrcweir                                 buf.append( service_name );
1055cdf0e10cSrcweir                                 throw registry::CannotRegisterImplementationException(
1056cdf0e10cSrcweir                                     buf.makeStringAndClear(), Reference< XInterface >() );
1057cdf0e10cSrcweir                             }
1058cdf0e10cSrcweir                         }
1059cdf0e10cSrcweir                         catch (container::NoSuchElementException & exc)
1060cdf0e10cSrcweir                         {
1061cdf0e10cSrcweir                             throw RuntimeException(
1062cdf0e10cSrcweir                                 OUSTR("cannot get service type description: ") + exc.Message,
1063cdf0e10cSrcweir                                 Reference< XInterface >() );
1064cdf0e10cSrcweir                         }
1065cdf0e10cSrcweir                     }
1066cdf0e10cSrcweir                 }
1067cdf0e10cSrcweir                 catch (registry::InvalidValueException &)
1068cdf0e10cSrcweir                 {
1069cdf0e10cSrcweir                     // repair
1070cdf0e10cSrcweir                     xKey2->setStringValue( service_name );
1071cdf0e10cSrcweir                 }
1072cdf0e10cSrcweir             }
1073cdf0e10cSrcweir             else
1074cdf0e10cSrcweir             {
1075cdf0e10cSrcweir                 // insert singleton entry
1076cdf0e10cSrcweir                 xKey2 = xDest->getRootKey()->createKey( keyname );
1077cdf0e10cSrcweir                 xKey2->setStringValue( service_name );
1078cdf0e10cSrcweir             }
1079cdf0e10cSrcweir 
1080cdf0e10cSrcweir             Reference< registry::XRegistryKey > xRegisteredImplNames(
1081cdf0e10cSrcweir                 xKey2->openKey( OUSTR("REGISTERED_BY") ) );
1082cdf0e10cSrcweir             if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
1083cdf0e10cSrcweir             {
1084cdf0e10cSrcweir                 // create
1085cdf0e10cSrcweir                 xRegisteredImplNames = xKey2->createKey( OUSTR("REGISTERED_BY") );
1086cdf0e10cSrcweir             }
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir             Sequence< OUString > implnames;
1089cdf0e10cSrcweir             try
1090cdf0e10cSrcweir             {
1091cdf0e10cSrcweir                 implnames = xRegisteredImplNames->getAsciiListValue();
1092cdf0e10cSrcweir             }
1093cdf0e10cSrcweir             catch (registry::InvalidValueException &)
1094cdf0e10cSrcweir             {
1095cdf0e10cSrcweir             }
1096cdf0e10cSrcweir             // check implname is already in
1097cdf0e10cSrcweir             sal_Int32 nPos_implnames = implnames.getLength();
1098cdf0e10cSrcweir             OUString const * pImplnames = implnames.getConstArray();
1099cdf0e10cSrcweir             while (nPos_implnames--)
1100cdf0e10cSrcweir             {
1101cdf0e10cSrcweir                 if (implname.equals( pImplnames[ nPos_implnames ] ))
1102cdf0e10cSrcweir                     break;
1103cdf0e10cSrcweir             }
1104cdf0e10cSrcweir             if (nPos_implnames < 0)
1105cdf0e10cSrcweir             {
1106cdf0e10cSrcweir                 // append and write back
1107cdf0e10cSrcweir                 implnames.realloc( implnames.getLength() +1 );
1108cdf0e10cSrcweir                 implnames[ implnames.getLength() -1 ] = implname;
1109cdf0e10cSrcweir                 xRegisteredImplNames->setAsciiListValue( implnames );
1110cdf0e10cSrcweir             }
1111cdf0e10cSrcweir         }
1112cdf0e10cSrcweir     }
1113cdf0e10cSrcweir }
1114cdf0e10cSrcweir 
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir //*************************************************************************
1117cdf0e10cSrcweir //	static prepareRegistry
1118cdf0e10cSrcweir //
prepareRegistry(const Reference<XSimpleRegistry> & xDest,const Reference<XRegistryKey> & xSource,const OUString & implementationLoaderUrl,const OUString & locationUrl,Reference<XComponentContext> const & xContext)1119cdf0e10cSrcweir static void prepareRegistry(
1120cdf0e10cSrcweir     const Reference < XSimpleRegistry >& xDest,
1121cdf0e10cSrcweir     const Reference < XRegistryKey >& xSource,
1122cdf0e10cSrcweir     const OUString& implementationLoaderUrl,
1123cdf0e10cSrcweir     const OUString& locationUrl,
1124cdf0e10cSrcweir     Reference< XComponentContext > const & xContext )
1125cdf0e10cSrcweir     // throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
1126cdf0e10cSrcweir {
1127cdf0e10cSrcweir     Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir     if (!subKeys.getLength())
1130cdf0e10cSrcweir     {
1131cdf0e10cSrcweir         throw InvalidRegistryException(
1132cdf0e10cSrcweir             OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): source registry is empty" ) ),
1133cdf0e10cSrcweir             Reference< XInterface > () );
1134cdf0e10cSrcweir     }
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir     const StringPool & pool = spool();
1137cdf0e10cSrcweir 
1138cdf0e10cSrcweir     const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1139cdf0e10cSrcweir     Reference < XRegistryKey > xImplKey;
1140cdf0e10cSrcweir 
1141cdf0e10cSrcweir     for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1142cdf0e10cSrcweir     {
1143cdf0e10cSrcweir         xImplKey = pSubKeys[i];
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir         Reference < XRegistryKey >  xKey = xImplKey->openKey(
1146cdf0e10cSrcweir             pool.slash_UNO_slash_SERVICES );
1147cdf0e10cSrcweir 
1148cdf0e10cSrcweir         if (xKey.is())
1149cdf0e10cSrcweir         {
1150cdf0e10cSrcweir             // update entries in SERVICES section
1151cdf0e10cSrcweir             Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
1152cdf0e10cSrcweir             const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir             OUString implName = OUString(xImplKey->getKeyName().getStr() + 1);
1155cdf0e10cSrcweir             sal_Int32 firstDot = implName.indexOf('/');
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir             if (firstDot >= 0)
1158cdf0e10cSrcweir                 implName = implName.copy(firstDot + 1);
1159cdf0e10cSrcweir 
1160cdf0e10cSrcweir             sal_Int32 offset = xKey->getKeyName().getLength() + 1;
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir             for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
1163cdf0e10cSrcweir             {
1164cdf0e10cSrcweir                 OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
1165cdf0e10cSrcweir 
1166cdf0e10cSrcweir                 createUniqueSubEntry(
1167cdf0e10cSrcweir                     xDest->getRootKey()->createKey(
1168cdf0e10cSrcweir                         pool.slash_SERVICES + serviceName ),
1169cdf0e10cSrcweir                     implName);
1170cdf0e10cSrcweir             }
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir             xKey = xImplKey->openKey( pool.slash_UNO );
1173cdf0e10cSrcweir             if (xKey.is())
1174cdf0e10cSrcweir             {
1175cdf0e10cSrcweir                 Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir                 if (subKeys2.getLength())
1178cdf0e10cSrcweir                 {
1179cdf0e10cSrcweir                     const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir                     for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
1182cdf0e10cSrcweir                     {
1183cdf0e10cSrcweir                         if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
1184cdf0e10cSrcweir                             pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
1185cdf0e10cSrcweir                             pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
1186cdf0e10cSrcweir                         {
1187cdf0e10cSrcweir                             prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, sal_True);
1188cdf0e10cSrcweir                         }
1189cdf0e10cSrcweir                     }
1190cdf0e10cSrcweir                 }
1191cdf0e10cSrcweir             }
1192cdf0e10cSrcweir         }
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir         // update LOCATION entry
1195cdf0e10cSrcweir         xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
1196cdf0e10cSrcweir 
1197cdf0e10cSrcweir         if (xKey.is())
1198cdf0e10cSrcweir         {
1199cdf0e10cSrcweir             xKey->setAsciiValue(locationUrl);
1200cdf0e10cSrcweir         }
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir         // update ACTIVATOR entry
1203cdf0e10cSrcweir         xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
1204cdf0e10cSrcweir 
1205cdf0e10cSrcweir         if (xKey.is())
1206cdf0e10cSrcweir         {
1207cdf0e10cSrcweir             xKey->setAsciiValue(implementationLoaderUrl);
1208cdf0e10cSrcweir         }
1209cdf0e10cSrcweir 
1210cdf0e10cSrcweir         xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir         if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
1213cdf0e10cSrcweir         {
1214cdf0e10cSrcweir             // update link entries in REGISTRY_LINKS section
1215cdf0e10cSrcweir             Sequence<OUString> linkNames = xKey->getAsciiListValue();
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir             if (linkNames.getLength())
1218cdf0e10cSrcweir             {
1219cdf0e10cSrcweir                 const OUString* pLinkNames = linkNames.getConstArray();
1220cdf0e10cSrcweir 
1221cdf0e10cSrcweir                 for (sal_Int32 j = 0; j < linkNames.getLength(); j++)
1222cdf0e10cSrcweir                 {
1223cdf0e10cSrcweir                     prepareLink(xDest, xImplKey, pLinkNames[j]);
1224cdf0e10cSrcweir                 }
1225cdf0e10cSrcweir             }
1226cdf0e10cSrcweir         }
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir         insert_singletons( xDest, xImplKey, xContext );
1229cdf0e10cSrcweir     }
1230cdf0e10cSrcweir }
1231cdf0e10cSrcweir 
1232cdf0e10cSrcweir 
findImplementations(const Reference<XRegistryKey> & xSource,std::list<OUString> & implNames)1233cdf0e10cSrcweir static void findImplementations(	const Reference < XRegistryKey > & xSource,
1234cdf0e10cSrcweir 									std::list <OUString>& implNames)
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir 	sal_Bool isImplKey = sal_False;
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir 	try
1239cdf0e10cSrcweir 	{
1240cdf0e10cSrcweir 		Reference < XRegistryKey > xKey = xSource->openKey(
1241cdf0e10cSrcweir 			spool().slash_UNO_slash_SERVICES );
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir 		if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
1244cdf0e10cSrcweir 		{
1245cdf0e10cSrcweir 			isImplKey = sal_True;
1246cdf0e10cSrcweir 
1247cdf0e10cSrcweir 			OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace('/', '.').getStr();
1248cdf0e10cSrcweir 			sal_Int32 firstDot = implName.indexOf('.');
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir 			if (firstDot >= 0)
1251cdf0e10cSrcweir 				implName = implName.copy(firstDot + 1);
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir 			implNames.push_back(implName);
1254cdf0e10cSrcweir 		}
1255cdf0e10cSrcweir 	}
1256cdf0e10cSrcweir 	catch(InvalidRegistryException&)
1257cdf0e10cSrcweir 	{
1258cdf0e10cSrcweir 	}
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir 	if (isImplKey) return;
1261cdf0e10cSrcweir 
1262cdf0e10cSrcweir 	try
1263cdf0e10cSrcweir 	{
1264cdf0e10cSrcweir 		Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1265cdf0e10cSrcweir 
1266cdf0e10cSrcweir 		if (subKeys.getLength() > 0)
1267cdf0e10cSrcweir 		{
1268cdf0e10cSrcweir 			const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1269cdf0e10cSrcweir 
1270cdf0e10cSrcweir 			for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1271cdf0e10cSrcweir 			{
1272cdf0e10cSrcweir 				findImplementations(pSubKeys[i], implNames);
1273cdf0e10cSrcweir 			}
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir 		}
1276cdf0e10cSrcweir 	}
1277cdf0e10cSrcweir 	catch(InvalidRegistryException&)
1278cdf0e10cSrcweir 	{
1279cdf0e10cSrcweir 	}
1280cdf0e10cSrcweir }
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir class ImplementationRegistration
1284cdf0e10cSrcweir 	: public WeakImplHelper3< XImplementationRegistration2, XServiceInfo, XInitialization >
1285cdf0e10cSrcweir {
1286cdf0e10cSrcweir public:
1287cdf0e10cSrcweir     ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
1288cdf0e10cSrcweir     ~ImplementationRegistration();
1289cdf0e10cSrcweir 
1290cdf0e10cSrcweir 	// XServiceInfo
1291cdf0e10cSrcweir 	OUString 						SAL_CALL getImplementationName() throw(RuntimeException);
1292cdf0e10cSrcweir     sal_Bool 						SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException);
1293cdf0e10cSrcweir     Sequence< OUString > 			SAL_CALL getSupportedServiceNames(void) throw(RuntimeException);
1294cdf0e10cSrcweir 
1295cdf0e10cSrcweir 	// XImplementationRegistration
1296cdf0e10cSrcweir     virtual void SAL_CALL registerImplementation(
1297cdf0e10cSrcweir 		const OUString& implementationLoader,
1298cdf0e10cSrcweir 		const OUString& location,
1299cdf0e10cSrcweir 		const Reference < XSimpleRegistry > & xReg)
1300cdf0e10cSrcweir 		throw(	CannotRegisterImplementationException, RuntimeException );
1301cdf0e10cSrcweir 
1302cdf0e10cSrcweir     virtual sal_Bool SAL_CALL revokeImplementation(
1303cdf0e10cSrcweir 		const OUString& location,
1304cdf0e10cSrcweir 		const Reference < XSimpleRegistry >& xReg)
1305cdf0e10cSrcweir 		throw( RuntimeException );
1306cdf0e10cSrcweir 
1307cdf0e10cSrcweir     virtual Sequence< OUString > SAL_CALL getImplementations(
1308cdf0e10cSrcweir 		const OUString& implementationLoader,
1309cdf0e10cSrcweir 		const OUString& location)
1310cdf0e10cSrcweir 		throw( RuntimeException );
1311cdf0e10cSrcweir     virtual Sequence< OUString > SAL_CALL checkInstantiation(
1312cdf0e10cSrcweir 		const OUString& implementationName)
1313cdf0e10cSrcweir 		throw( RuntimeException );
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir 	// XImplementationRegistration2
1316cdf0e10cSrcweir     virtual void SAL_CALL registerImplementationWithLocation(
1317cdf0e10cSrcweir 		const OUString& implementationLoader,
1318cdf0e10cSrcweir 		const OUString& location,
1319cdf0e10cSrcweir         const OUString& registeredLocation,
1320cdf0e10cSrcweir 		const Reference < XSimpleRegistry > & xReg)
1321cdf0e10cSrcweir 		throw(	CannotRegisterImplementationException, RuntimeException );
1322cdf0e10cSrcweir 
1323cdf0e10cSrcweir     // XInitialization
1324cdf0e10cSrcweir     virtual void SAL_CALL initialize(
1325cdf0e10cSrcweir 		const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
1326cdf0e10cSrcweir 		throw(	::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
1327cdf0e10cSrcweir 
1328cdf0e10cSrcweir private: // helper methods
1329cdf0e10cSrcweir     void prepareRegister(
1330cdf0e10cSrcweir 		const OUString& implementationLoader,
1331cdf0e10cSrcweir 		const OUString& location,
1332cdf0e10cSrcweir         const OUString& registeredLocation,
1333cdf0e10cSrcweir 		const Reference < XSimpleRegistry > & xReg);
1334cdf0e10cSrcweir     // throw( CannotRegisterImplementationException, RuntimeException )
1335cdf0e10cSrcweir 
1336cdf0e10cSrcweir 	static void doRegister(	const Reference < XMultiComponentFactory >& xSMgr,
1337cdf0e10cSrcweir                             const Reference < XComponentContext > &xCtx,
1338cdf0e10cSrcweir                             const Reference < XImplementationLoader >& xAct,
1339cdf0e10cSrcweir                             const Reference < XSimpleRegistry >& xDest,
1340cdf0e10cSrcweir                             const OUString& implementationLoaderUrl,
1341cdf0e10cSrcweir                             const OUString& locationUrl,
1342cdf0e10cSrcweir                             const OUString& registeredLocationUrl);
1343cdf0e10cSrcweir         /* throw ( InvalidRegistryException,
1344cdf0e10cSrcweir                    MergeConflictException,
1345cdf0e10cSrcweir                    CannotRegisterImplementationException, RuntimeException ) */
1346cdf0e10cSrcweir 
1347cdf0e10cSrcweir     static void doRevoke( const Reference < XSimpleRegistry >& xDest,
1348cdf0e10cSrcweir                           const OUString& locationUrl );
1349cdf0e10cSrcweir         // throw( InvalidRegistryException, RuntimeException )
1350cdf0e10cSrcweir 	Reference< XSimpleRegistry > getRegistryFromServiceManager();
1351cdf0e10cSrcweir 
1352cdf0e10cSrcweir 	static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
1353cdf0e10cSrcweir 		const Reference< XMultiComponentFactory > &rSMgr,
1354cdf0e10cSrcweir 		const Reference < XComponentContext > & rCtx );
1355cdf0e10cSrcweir 
1356cdf0e10cSrcweir private: // members
1357cdf0e10cSrcweir 	Reference < XMultiComponentFactory >	m_xSMgr;
1358cdf0e10cSrcweir 	Reference < XComponentContext >         m_xCtx;
1359cdf0e10cSrcweir };
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir //*************************************************************************
1362cdf0e10cSrcweir // ImplementationRegistration()
1363cdf0e10cSrcweir //
ImplementationRegistration(const Reference<XComponentContext> & xCtx)1364cdf0e10cSrcweir ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
1365cdf0e10cSrcweir 	: m_xSMgr( xCtx->getServiceManager() )
1366cdf0e10cSrcweir 	, m_xCtx( xCtx )
1367cdf0e10cSrcweir {
1368cdf0e10cSrcweir 	g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
1369cdf0e10cSrcweir }
1370cdf0e10cSrcweir 
1371cdf0e10cSrcweir //*************************************************************************
1372cdf0e10cSrcweir // ~ImplementationRegistration()
1373cdf0e10cSrcweir //
~ImplementationRegistration()1374cdf0e10cSrcweir ImplementationRegistration::~ImplementationRegistration()
1375cdf0e10cSrcweir {
1376cdf0e10cSrcweir 	g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
1377cdf0e10cSrcweir }
1378cdf0e10cSrcweir 
1379cdf0e10cSrcweir 
1380cdf0e10cSrcweir // XServiceInfo
getImplementationName()1381cdf0e10cSrcweir OUString ImplementationRegistration::getImplementationName() throw(RuntimeException)
1382cdf0e10cSrcweir {
1383cdf0e10cSrcweir 	return stoc_bootstrap::impreg_getImplementationName();
1384cdf0e10cSrcweir }
1385cdf0e10cSrcweir 
1386cdf0e10cSrcweir // XServiceInfo
supportsService(const OUString & ServiceName)1387cdf0e10cSrcweir sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw(RuntimeException)
1388cdf0e10cSrcweir {
1389cdf0e10cSrcweir 	Sequence< OUString > aSNL = getSupportedServiceNames();
1390cdf0e10cSrcweir 	const OUString * pArray = aSNL.getConstArray();
1391cdf0e10cSrcweir 	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1392cdf0e10cSrcweir 		if( pArray[i] == ServiceName )
1393cdf0e10cSrcweir 			return sal_True;
1394cdf0e10cSrcweir 	return sal_False;
1395cdf0e10cSrcweir }
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir // XServiceInfo
getSupportedServiceNames(void)1398cdf0e10cSrcweir Sequence< OUString > ImplementationRegistration::getSupportedServiceNames(void) throw(RuntimeException)
1399cdf0e10cSrcweir {
1400cdf0e10cSrcweir 	return stoc_bootstrap::impreg_getSupportedServiceNames();
1401cdf0e10cSrcweir }
1402cdf0e10cSrcweir 
getRegistryFromServiceManager()1403cdf0e10cSrcweir Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
1404cdf0e10cSrcweir {
1405cdf0e10cSrcweir 	Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
1406cdf0e10cSrcweir 	Reference < XSimpleRegistry > xRegistry;
1407cdf0e10cSrcweir 
1408cdf0e10cSrcweir 	if( xPropSet.is() ) {
1409cdf0e10cSrcweir 
1410cdf0e10cSrcweir 		try {  // the implementation does not support XIntrospectionAccess !
1411cdf0e10cSrcweir 
1412cdf0e10cSrcweir 			Any aAny = xPropSet->getPropertyValue( spool().Registry );
1413cdf0e10cSrcweir 
1414cdf0e10cSrcweir 			if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )	{
1415cdf0e10cSrcweir 				aAny >>= xRegistry;
1416cdf0e10cSrcweir 			}
1417cdf0e10cSrcweir 	 	}
1418cdf0e10cSrcweir 	 	catch( UnknownPropertyException & ) {
1419cdf0e10cSrcweir 	 		// empty reference is error signal !
1420cdf0e10cSrcweir 		}
1421cdf0e10cSrcweir 	}
1422cdf0e10cSrcweir 
1423cdf0e10cSrcweir 	return xRegistry;
1424cdf0e10cSrcweir }
1425cdf0e10cSrcweir 
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir //************************************************************************
1428cdf0e10cSrcweir // XInitialization
1429cdf0e10cSrcweir //
initialize(const::com::sun::star::uno::Sequence<::com::sun::star::uno::Any> & aArgs)1430cdf0e10cSrcweir void ImplementationRegistration::initialize(
1431cdf0e10cSrcweir 	const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs )
1432cdf0e10cSrcweir 	throw(	::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1433cdf0e10cSrcweir {
1434cdf0e10cSrcweir 
1435cdf0e10cSrcweir 	if( aArgs.getLength() != 4 ) {
1436cdf0e10cSrcweir         OUStringBuffer buf;
1437cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1438cdf0e10cSrcweir             "ImplementationRegistration::initialize() expects 4 parameters, got "));
1439cdf0e10cSrcweir         buf.append( (sal_Int32) aArgs.getLength() );
1440cdf0e10cSrcweir 		throw IllegalArgumentException( buf.makeStringAndClear(),
1441cdf0e10cSrcweir                                         Reference<XInterface > (),
1442cdf0e10cSrcweir                                         0 );
1443cdf0e10cSrcweir 	}
1444cdf0e10cSrcweir 
1445cdf0e10cSrcweir 	Reference< XImplementationLoader > rLoader;
1446cdf0e10cSrcweir 	OUString loaderServiceName;
1447cdf0e10cSrcweir 	OUString locationUrl;
1448cdf0e10cSrcweir 	Reference< XSimpleRegistry > rReg;
1449cdf0e10cSrcweir 
1450cdf0e10cSrcweir 	// 1st argument : An instance of an implementation loader
1451cdf0e10cSrcweir 	if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1452cdf0e10cSrcweir 		aArgs.getConstArray()[0] >>= rLoader;
1453cdf0e10cSrcweir 	}
1454cdf0e10cSrcweir 	if( !rLoader.is()) {
1455cdf0e10cSrcweir         OUStringBuffer buf;
1456cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1457cdf0e10cSrcweir             "ImplementationRegistration::initialize() invalid first parameter,"
1458cdf0e10cSrcweir             "expected " ) );
1459cdf0e10cSrcweir         buf.append( getCppuType( &rLoader ).getTypeName() );
1460cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", got " ) );
1461cdf0e10cSrcweir         buf.append( aArgs.getConstArray()[0].getValueTypeName() );
1462cdf0e10cSrcweir 		throw IllegalArgumentException( buf.makeStringAndClear(),
1463cdf0e10cSrcweir                                         Reference< XInterface > (),
1464cdf0e10cSrcweir                                         0 );
1465cdf0e10cSrcweir 	}
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir 	// 2nd argument : The service name of the loader. This name is written into the registry
1468cdf0e10cSrcweir 	if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
1469cdf0e10cSrcweir 		aArgs.getConstArray()[1] >>= loaderServiceName;
1470cdf0e10cSrcweir 	}
1471cdf0e10cSrcweir 	if( ! loaderServiceName.getLength() ) {
1472cdf0e10cSrcweir         OUStringBuffer buf;
1473cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1474cdf0e10cSrcweir             "ImplementationRegistration::initialize() invalid second parameter,"
1475cdf0e10cSrcweir             "expected string, got " ) );
1476cdf0e10cSrcweir         buf.append( aArgs.getConstArray()[1].getValueTypeName() );
1477cdf0e10cSrcweir 		throw IllegalArgumentException( buf.makeStringAndClear(),
1478cdf0e10cSrcweir                                         Reference< XInterface > (),
1479cdf0e10cSrcweir                                         0 );
1480cdf0e10cSrcweir 	}
1481cdf0e10cSrcweir 
1482cdf0e10cSrcweir 	// 3rd argument : The file name of the dll, that contains the loader
1483cdf0e10cSrcweir 	if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
1484cdf0e10cSrcweir 		aArgs.getConstArray()[2] >>= locationUrl;
1485cdf0e10cSrcweir 	}
1486cdf0e10cSrcweir 	if( ! locationUrl.getLength() ) {
1487cdf0e10cSrcweir         OUStringBuffer buf;
1488cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1489cdf0e10cSrcweir             "ImplementationRegistration::initialize() invalid third parameter,"
1490cdf0e10cSrcweir             "expected string, got " ) );
1491cdf0e10cSrcweir         buf.append( aArgs.getConstArray()[2].getValueTypeName() );
1492cdf0e10cSrcweir 		throw IllegalArgumentException( buf.makeStringAndClear(),
1493cdf0e10cSrcweir                                         Reference< XInterface > (),
1494cdf0e10cSrcweir                                         0 );
1495cdf0e10cSrcweir 	}
1496cdf0e10cSrcweir 
1497cdf0e10cSrcweir 	// 4th argument : The registry, the service should be written to
1498cdf0e10cSrcweir 	if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
1499cdf0e10cSrcweir 		aArgs.getConstArray()[3] >>= rReg;
1500cdf0e10cSrcweir 	}
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir 	if( !rReg.is() ) {
1503cdf0e10cSrcweir 		rReg = getRegistryFromServiceManager();
1504cdf0e10cSrcweir 		if( !rReg.is() ) {
1505cdf0e10cSrcweir             OUStringBuffer buf;
1506cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1507cdf0e10cSrcweir                 "ImplementationRegistration::initialize() invalid fourth parameter,"
1508cdf0e10cSrcweir                 "expected " ));
1509cdf0e10cSrcweir             buf.append( getCppuType( &rReg ).getTypeName() );
1510cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", got " ) );
1511cdf0e10cSrcweir             buf.append( aArgs.getConstArray()[3].getValueTypeName() );
1512cdf0e10cSrcweir             throw IllegalArgumentException( buf.makeStringAndClear(),
1513cdf0e10cSrcweir                                             Reference< XInterface > (),
1514cdf0e10cSrcweir                                             0 );
1515cdf0e10cSrcweir 		}
1516cdf0e10cSrcweir 	}
1517cdf0e10cSrcweir 
1518cdf0e10cSrcweir 	doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
1519cdf0e10cSrcweir }
1520cdf0e10cSrcweir 
1521cdf0e10cSrcweir 
1522cdf0e10cSrcweir 
1523cdf0e10cSrcweir //*************************************************************************
1524cdf0e10cSrcweir // virtual function registerImplementationWithLocation of XImplementationRegistration2
1525cdf0e10cSrcweir //
registerImplementationWithLocation(const OUString & implementationLoaderUrl,const OUString & locationUrl,const OUString & registeredLocationUrl,const Reference<XSimpleRegistry> & xReg)1526cdf0e10cSrcweir void ImplementationRegistration::registerImplementationWithLocation(
1527cdf0e10cSrcweir 	const OUString& implementationLoaderUrl,
1528cdf0e10cSrcweir 	const OUString& locationUrl,
1529cdf0e10cSrcweir     const OUString& registeredLocationUrl,
1530cdf0e10cSrcweir 	const Reference < XSimpleRegistry > & xReg)
1531cdf0e10cSrcweir 	throw( CannotRegisterImplementationException, RuntimeException )
1532cdf0e10cSrcweir {
1533cdf0e10cSrcweir     prepareRegister(
1534cdf0e10cSrcweir         implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
1535cdf0e10cSrcweir }
1536cdf0e10cSrcweir 
1537cdf0e10cSrcweir // helper function
prepareRegister(const OUString & implementationLoaderUrl,const OUString & locationUrl,const OUString & registeredLocationUrl,const Reference<XSimpleRegistry> & xReg)1538cdf0e10cSrcweir void ImplementationRegistration::prepareRegister(
1539cdf0e10cSrcweir 	const OUString& implementationLoaderUrl,
1540cdf0e10cSrcweir 	const OUString& locationUrl,
1541cdf0e10cSrcweir     const OUString& registeredLocationUrl,
1542cdf0e10cSrcweir 	const Reference < XSimpleRegistry > & xReg)
1543cdf0e10cSrcweir 	// throw( CannotRegisterImplementationException, RuntimeException )
1544cdf0e10cSrcweir {
1545cdf0e10cSrcweir 	OUString implLoaderUrl(implementationLoaderUrl);
1546cdf0e10cSrcweir 	OUString activatorName;
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir 	if (implementationLoaderUrl.getLength() > 0)
1549cdf0e10cSrcweir 	{
1550cdf0e10cSrcweir 		OUString tmpActivator(implementationLoaderUrl);
1551cdf0e10cSrcweir         sal_Int32 nIndex = 0;
1552cdf0e10cSrcweir 		activatorName = tmpActivator.getToken(0, ':', nIndex );
1553cdf0e10cSrcweir 	} else
1554cdf0e10cSrcweir 	{
1555cdf0e10cSrcweir 		// check locationUrl to find out what kind of loader is needed
1556cdf0e10cSrcweir 		// set iimplLoaderUrl
1557cdf0e10cSrcweir 	}
1558cdf0e10cSrcweir 
1559cdf0e10cSrcweir 	if( m_xSMgr.is() ) {
1560cdf0e10cSrcweir         try
1561cdf0e10cSrcweir         {
1562cdf0e10cSrcweir             Reference < XImplementationLoader > xAct(
1563cdf0e10cSrcweir                 m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1564cdf0e10cSrcweir             if (xAct.is())
1565cdf0e10cSrcweir             {
1566cdf0e10cSrcweir                 Reference < XSimpleRegistry > xRegistry;
1567cdf0e10cSrcweir 
1568cdf0e10cSrcweir                 if (xReg.is())
1569cdf0e10cSrcweir                 {
1570cdf0e10cSrcweir                     // registry supplied by user
1571cdf0e10cSrcweir                     xRegistry = xReg;
1572cdf0e10cSrcweir                 }
1573cdf0e10cSrcweir                 else
1574cdf0e10cSrcweir                 {
1575cdf0e10cSrcweir                     xRegistry = getRegistryFromServiceManager();
1576cdf0e10cSrcweir                 }
1577cdf0e10cSrcweir 
1578cdf0e10cSrcweir                 if ( xRegistry.is())
1579cdf0e10cSrcweir                 {
1580cdf0e10cSrcweir                     doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implLoaderUrl,
1581cdf0e10cSrcweir                                locationUrl, registeredLocationUrl);
1582cdf0e10cSrcweir                 }
1583cdf0e10cSrcweir             }
1584cdf0e10cSrcweir             else
1585cdf0e10cSrcweir             {
1586cdf0e10cSrcweir                 OUStringBuffer buf( 128 );
1587cdf0e10cSrcweir                 buf.appendAscii( "ImplementationRegistration::registerImplementation() - The service " );
1588cdf0e10cSrcweir                 buf.append( activatorName );
1589cdf0e10cSrcweir                 buf.appendAscii( " cannot be instantiated\n" );
1590cdf0e10cSrcweir                 throw CannotRegisterImplementationException(
1591cdf0e10cSrcweir                     buf.makeStringAndClear(), Reference< XInterface > () );
1592cdf0e10cSrcweir             }
1593cdf0e10cSrcweir         }
1594cdf0e10cSrcweir         catch( CannotRegisterImplementationException & )
1595cdf0e10cSrcweir         {
1596cdf0e10cSrcweir             throw;
1597cdf0e10cSrcweir         }
1598cdf0e10cSrcweir         catch( InvalidRegistryException & e )
1599cdf0e10cSrcweir         {
1600cdf0e10cSrcweir             OUStringBuffer buf;
1601cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1602cdf0e10cSrcweir                 "ImplementationRegistration::registerImplementation() "
1603cdf0e10cSrcweir                 "InvalidRegistryException during registration (" ));
1604cdf0e10cSrcweir             buf.append( e.Message );
1605cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1606cdf0e10cSrcweir             throw CannotRegisterImplementationException(
1607cdf0e10cSrcweir                 buf.makeStringAndClear(), Reference< XInterface > () );
1608cdf0e10cSrcweir         }
1609cdf0e10cSrcweir         catch( MergeConflictException & e )
1610cdf0e10cSrcweir         {
1611cdf0e10cSrcweir             OUStringBuffer buf;
1612cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
1613cdf0e10cSrcweir                 "ImplementationRegistration::registerImplementation() "
1614cdf0e10cSrcweir                 "MergeConflictException during registration (" ));
1615cdf0e10cSrcweir             buf.append( e.Message );
1616cdf0e10cSrcweir             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
1617cdf0e10cSrcweir             throw CannotRegisterImplementationException(
1618cdf0e10cSrcweir                 buf.makeStringAndClear(), Reference< XInterface > () );
1619cdf0e10cSrcweir         }
1620cdf0e10cSrcweir 	}
1621cdf0e10cSrcweir 	else
1622cdf0e10cSrcweir     {
1623cdf0e10cSrcweir         throw CannotRegisterImplementationException(
1624cdf0e10cSrcweir             OUString(RTL_CONSTASCII_USTRINGPARAM(
1625cdf0e10cSrcweir                 "ImplementationRegistration::registerImplementation() "
1626cdf0e10cSrcweir                 "no componentcontext available to instantiate loader")),
1627cdf0e10cSrcweir             Reference< XInterface > () );
1628cdf0e10cSrcweir     }
1629cdf0e10cSrcweir }
1630cdf0e10cSrcweir 
1631cdf0e10cSrcweir //*************************************************************************
1632cdf0e10cSrcweir // virtual function registerImplementation of XImplementationRegistration
1633cdf0e10cSrcweir //
registerImplementation(const OUString & implementationLoaderUrl,const OUString & locationUrl,const Reference<XSimpleRegistry> & xReg)1634cdf0e10cSrcweir void ImplementationRegistration::registerImplementation(
1635cdf0e10cSrcweir 	const OUString& implementationLoaderUrl,
1636cdf0e10cSrcweir 	const OUString& locationUrl,
1637cdf0e10cSrcweir 	const Reference < XSimpleRegistry > & xReg)
1638cdf0e10cSrcweir 	throw( CannotRegisterImplementationException, RuntimeException )
1639cdf0e10cSrcweir {
1640cdf0e10cSrcweir     prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1641cdf0e10cSrcweir }
1642cdf0e10cSrcweir 
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir //*************************************************************************
1645cdf0e10cSrcweir // virtual function revokeImplementation of XImplementationRegistration
1646cdf0e10cSrcweir //
revokeImplementation(const OUString & location,const Reference<XSimpleRegistry> & xReg)1647cdf0e10cSrcweir sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
1648cdf0e10cSrcweir 													  const Reference < XSimpleRegistry >& xReg)
1649cdf0e10cSrcweir 	throw ( RuntimeException )
1650cdf0e10cSrcweir {
1651cdf0e10cSrcweir 	sal_Bool ret = sal_False;
1652cdf0e10cSrcweir 
1653cdf0e10cSrcweir 	Reference < XSimpleRegistry > xRegistry;
1654cdf0e10cSrcweir 
1655cdf0e10cSrcweir 	if (xReg.is()) {
1656cdf0e10cSrcweir 		xRegistry = xReg;
1657cdf0e10cSrcweir 	}
1658cdf0e10cSrcweir 	else {
1659cdf0e10cSrcweir 		Reference < XPropertySet > xPropSet = Reference< XPropertySet >::query( m_xSMgr );
1660cdf0e10cSrcweir 		if( xPropSet.is() ) {
1661cdf0e10cSrcweir 			try {
1662cdf0e10cSrcweir 				Any aAny = xPropSet->getPropertyValue( spool().Registry );
1663cdf0e10cSrcweir 
1664cdf0e10cSrcweir 				if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
1665cdf0e10cSrcweir 				{
1666cdf0e10cSrcweir 					aAny >>= xRegistry;
1667cdf0e10cSrcweir 				}
1668cdf0e10cSrcweir 			}
1669cdf0e10cSrcweir 			catch ( UnknownPropertyException & ) {
1670cdf0e10cSrcweir 			}
1671cdf0e10cSrcweir 		}
1672cdf0e10cSrcweir 	}
1673cdf0e10cSrcweir 
1674cdf0e10cSrcweir 	if (xRegistry.is())
1675cdf0e10cSrcweir 	{
1676cdf0e10cSrcweir         try
1677cdf0e10cSrcweir         {
1678cdf0e10cSrcweir             doRevoke(xRegistry, location);
1679cdf0e10cSrcweir             ret = sal_True;
1680cdf0e10cSrcweir         }
1681cdf0e10cSrcweir         catch( InvalidRegistryException & )
1682cdf0e10cSrcweir         {
1683cdf0e10cSrcweir             // no way to transport the error, as no exception is specified and a runtime
1684cdf0e10cSrcweir             // exception is not appropriate.
1685cdf0e10cSrcweir             OSL_ENSURE( 0 , "InvalidRegistryException during revokeImplementation" );
1686cdf0e10cSrcweir         }
1687cdf0e10cSrcweir 	}
1688cdf0e10cSrcweir 
1689cdf0e10cSrcweir 	return ret;
1690cdf0e10cSrcweir }
1691cdf0e10cSrcweir 
1692cdf0e10cSrcweir //*************************************************************************
1693cdf0e10cSrcweir // virtual function getImplementations of XImplementationRegistration
1694cdf0e10cSrcweir //
getImplementations(const OUString & implementationLoaderUrl,const OUString & locationUrl)1695cdf0e10cSrcweir Sequence< OUString > ImplementationRegistration::getImplementations(
1696cdf0e10cSrcweir 	const OUString & implementationLoaderUrl,
1697cdf0e10cSrcweir 	const OUString & locationUrl)
1698cdf0e10cSrcweir 	throw ( RuntimeException )
1699cdf0e10cSrcweir {
1700cdf0e10cSrcweir 	OUString implLoaderUrl(implementationLoaderUrl);
1701cdf0e10cSrcweir 	OUString activatorName;
1702cdf0e10cSrcweir 
1703cdf0e10cSrcweir 	if (implementationLoaderUrl.getLength() > 0)
1704cdf0e10cSrcweir 	{
1705cdf0e10cSrcweir 		OUString tmpActivator(implementationLoaderUrl);
1706cdf0e10cSrcweir         sal_Int32 nIndex = 0;
1707cdf0e10cSrcweir 		activatorName = tmpActivator.getToken(0, ':', nIndex );
1708cdf0e10cSrcweir 	} else
1709cdf0e10cSrcweir 	{
1710cdf0e10cSrcweir 		// check locationUrl to find out what kind of loader is needed
1711cdf0e10cSrcweir 		// set implLoaderUrl
1712cdf0e10cSrcweir 	}
1713cdf0e10cSrcweir 
1714cdf0e10cSrcweir 	if( m_xSMgr.is() ) {
1715cdf0e10cSrcweir 
1716cdf0e10cSrcweir 		Reference < XImplementationLoader > xAct(
1717cdf0e10cSrcweir 			m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1718cdf0e10cSrcweir 
1719cdf0e10cSrcweir 		if (xAct.is())
1720cdf0e10cSrcweir 		{
1721cdf0e10cSrcweir 
1722cdf0e10cSrcweir 			Reference < XSimpleRegistry > xReg =
1723cdf0e10cSrcweir 				createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1724cdf0e10cSrcweir 
1725cdf0e10cSrcweir 			if (xReg.is())
1726cdf0e10cSrcweir 			{
1727cdf0e10cSrcweir 				try
1728cdf0e10cSrcweir 				{
1729cdf0e10cSrcweir 					xReg->open(OUString() /* in mem */, sal_False, sal_True);
1730cdf0e10cSrcweir 					Reference < XRegistryKey > xImpl;
1731cdf0e10cSrcweir 
1732cdf0e10cSrcweir 					{ // only necessary	for deleting the temporary variable of rootkey
1733cdf0e10cSrcweir 						xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1734cdf0e10cSrcweir 					}
1735cdf0e10cSrcweir 					if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1736cdf0e10cSrcweir 					{
1737cdf0e10cSrcweir 						std::list <OUString> implNames;
1738cdf0e10cSrcweir 
1739cdf0e10cSrcweir 						findImplementations(xImpl, implNames);
1740cdf0e10cSrcweir 
1741cdf0e10cSrcweir 						if (!implNames.empty())
1742cdf0e10cSrcweir 						{
1743cdf0e10cSrcweir 							std::list<OUString>::const_iterator iter = implNames.begin();
1744cdf0e10cSrcweir 
1745cdf0e10cSrcweir 							Sequence<OUString> seqImpl(implNames.size());
1746cdf0e10cSrcweir 							OUString *pImplNames = seqImpl.getArray();
1747cdf0e10cSrcweir 
1748cdf0e10cSrcweir 							sal_Int32 index = 0;
1749cdf0e10cSrcweir 							while (iter != implNames.end())
1750cdf0e10cSrcweir 							{
1751cdf0e10cSrcweir 								pImplNames[index] = *iter;
1752cdf0e10cSrcweir 								index++;
1753cdf0e10cSrcweir 								++iter;
1754cdf0e10cSrcweir 							}
1755cdf0e10cSrcweir 
1756cdf0e10cSrcweir 							xImpl->closeKey();
1757cdf0e10cSrcweir 							return seqImpl;
1758cdf0e10cSrcweir 						}
1759cdf0e10cSrcweir 					}
1760cdf0e10cSrcweir 
1761cdf0e10cSrcweir 					xImpl->closeKey();
1762cdf0e10cSrcweir 				}
1763cdf0e10cSrcweir 				catch(MergeConflictException&)
1764cdf0e10cSrcweir 				{
1765cdf0e10cSrcweir 				}
1766cdf0e10cSrcweir 				catch(InvalidRegistryException&)
1767cdf0e10cSrcweir 				{
1768cdf0e10cSrcweir 				}
1769cdf0e10cSrcweir 			}
1770cdf0e10cSrcweir 		}
1771cdf0e10cSrcweir 	}
1772cdf0e10cSrcweir 
1773cdf0e10cSrcweir 	return Sequence<OUString>();
1774cdf0e10cSrcweir }
1775cdf0e10cSrcweir 
1776cdf0e10cSrcweir //*************************************************************************
1777cdf0e10cSrcweir // virtual function checkInstantiation of XImplementationRegistration
1778cdf0e10cSrcweir //
checkInstantiation(const OUString &)1779cdf0e10cSrcweir Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
1780cdf0e10cSrcweir 	throw ( RuntimeException )
1781cdf0e10cSrcweir {
1782cdf0e10cSrcweir 	OSL_ENSURE( sal_False, "ImplementationRegistration::checkInstantiation not implemented" );
1783cdf0e10cSrcweir 	return Sequence<OUString>();
1784cdf0e10cSrcweir }
1785cdf0e10cSrcweir 
1786cdf0e10cSrcweir //*************************************************************************
1787cdf0e10cSrcweir // helper function doRegistration
1788cdf0e10cSrcweir //
1789cdf0e10cSrcweir 
doRevoke(const Reference<XSimpleRegistry> & xDest,const OUString & locationUrl)1790cdf0e10cSrcweir void ImplementationRegistration::doRevoke(
1791cdf0e10cSrcweir 	const Reference < XSimpleRegistry >& xDest,
1792cdf0e10cSrcweir 	const OUString& locationUrl)
1793cdf0e10cSrcweir     // throw ( InvalidRegistryException, RuntimeException )
1794cdf0e10cSrcweir {
1795cdf0e10cSrcweir     if( xDest.is() )
1796cdf0e10cSrcweir     {
1797cdf0e10cSrcweir         std::list<OUString> aNames;
1798cdf0e10cSrcweir 
1799cdf0e10cSrcweir         const StringPool &pool = spool();
1800cdf0e10cSrcweir         Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1801cdf0e10cSrcweir 
1802cdf0e10cSrcweir         Reference < XRegistryKey > xKey =
1803cdf0e10cSrcweir             xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
1804cdf0e10cSrcweir         if (xKey.is() && xKey->isValid())
1805cdf0e10cSrcweir         {
1806cdf0e10cSrcweir             deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1807cdf0e10cSrcweir         }
1808cdf0e10cSrcweir 
1809cdf0e10cSrcweir         xKey = xRootKey->openKey( pool.slash_SERVICES );
1810cdf0e10cSrcweir         if (xKey.is())
1811cdf0e10cSrcweir         {
1812cdf0e10cSrcweir             std::list<OUString>::const_iterator iter = aNames.begin();
1813cdf0e10cSrcweir 
1814cdf0e10cSrcweir             while (iter != aNames.end())
1815cdf0e10cSrcweir             {
1816cdf0e10cSrcweir                 deleteAllServiceEntries(xDest, xKey, *iter);
1817cdf0e10cSrcweir                 ++iter;
1818cdf0e10cSrcweir             }
1819cdf0e10cSrcweir         }
1820cdf0e10cSrcweir 
1821cdf0e10cSrcweir         xKey = xRootKey->openKey( OUSTR("/SINGLETONS") );
1822cdf0e10cSrcweir         if (xKey.is() && xKey->isValid())
1823cdf0e10cSrcweir         {
1824cdf0e10cSrcweir             delete_all_singleton_entries( xKey, aNames );
1825cdf0e10cSrcweir         }
1826cdf0e10cSrcweir 
1827cdf0e10cSrcweir         if (xRootKey.is())
1828cdf0e10cSrcweir             xRootKey->closeKey();
1829cdf0e10cSrcweir         if (xKey.is() && xKey->isValid() )
1830cdf0e10cSrcweir             xKey->closeKey();
1831cdf0e10cSrcweir     }
1832cdf0e10cSrcweir }
1833cdf0e10cSrcweir 
doRegister(const Reference<XMultiComponentFactory> & xSMgr,const Reference<XComponentContext> & xCtx,const Reference<XImplementationLoader> & xAct,const Reference<XSimpleRegistry> & xDest,const OUString & implementationLoaderUrl,const OUString & locationUrl,const OUString & registeredLocationUrl)1834cdf0e10cSrcweir void ImplementationRegistration::doRegister(
1835cdf0e10cSrcweir 	const Reference< XMultiComponentFactory > & xSMgr,
1836cdf0e10cSrcweir 	const Reference< XComponentContext > &xCtx,
1837cdf0e10cSrcweir 	const Reference < XImplementationLoader > & xAct,
1838cdf0e10cSrcweir 	const Reference < XSimpleRegistry >& xDest,
1839cdf0e10cSrcweir 	const OUString& implementationLoaderUrl,
1840cdf0e10cSrcweir 	const OUString& locationUrl,
1841cdf0e10cSrcweir     const OUString& registeredLocationUrl)
1842cdf0e10cSrcweir     /* throw ( InvalidRegistryException,
1843cdf0e10cSrcweir                MergeConflictException,
1844cdf0e10cSrcweir                CannotRegisterImplementationException, RuntimeException ) */
1845cdf0e10cSrcweir {
1846cdf0e10cSrcweir     Reference < XSimpleRegistry > 	xReg =
1847cdf0e10cSrcweir         createTemporarySimpleRegistry( xSMgr, xCtx );
1848cdf0e10cSrcweir     Reference < XRegistryKey > 		xSourceKey;
1849cdf0e10cSrcweir 
1850cdf0e10cSrcweir     if (xAct.is() && xReg.is() && xDest.is())
1851cdf0e10cSrcweir     {
1852cdf0e10cSrcweir         try
1853cdf0e10cSrcweir         {
1854cdf0e10cSrcweir             xReg->open(OUString() /* in mem */, sal_False, sal_True);
1855cdf0e10cSrcweir 
1856cdf0e10cSrcweir             { // only necessary	for deleting the temporary variable of rootkey
1857cdf0e10cSrcweir                 xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1858cdf0e10cSrcweir             }
1859cdf0e10cSrcweir 
1860cdf0e10cSrcweir             sal_Bool bSuccess =
1861cdf0e10cSrcweir                 xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1862cdf0e10cSrcweir             if ( bSuccess )
1863cdf0e10cSrcweir             {
1864cdf0e10cSrcweir                 prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1865cdf0e10cSrcweir 
1866cdf0e10cSrcweir                 xSourceKey->closeKey();
1867cdf0e10cSrcweir 
1868cdf0e10cSrcweir                 xSourceKey = xReg->getRootKey();
1869cdf0e10cSrcweir                 Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1870cdf0e10cSrcweir                 mergeKeys( xDestKey, xSourceKey );
1871cdf0e10cSrcweir                 xDestKey->closeKey();
1872cdf0e10cSrcweir                 xSourceKey->closeKey();
1873cdf0e10cSrcweir             }
1874cdf0e10cSrcweir             else
1875cdf0e10cSrcweir             {
1876cdf0e10cSrcweir                 throw CannotRegisterImplementationException(
1877cdf0e10cSrcweir                     OUString( RTL_CONSTASCII_USTRINGPARAM( "ImplementationRegistration::doRegistration() component registration signaled failure" ) ),
1878cdf0e10cSrcweir                     Reference< XInterface > () );
1879cdf0e10cSrcweir             }
1880cdf0e10cSrcweir 
1881cdf0e10cSrcweir             // Cleanup Source registry.
1882cdf0e10cSrcweir             if ( xSourceKey->isValid() )
1883cdf0e10cSrcweir                 xSourceKey->closeKey();
1884cdf0e10cSrcweir         }
1885cdf0e10cSrcweir         catch(CannotRegisterImplementationException&)
1886cdf0e10cSrcweir         {
1887cdf0e10cSrcweir             if ( xSourceKey->isValid() )
1888cdf0e10cSrcweir                 xSourceKey->closeKey();
1889cdf0e10cSrcweir             // and throw again
1890cdf0e10cSrcweir             throw;
1891cdf0e10cSrcweir         }
1892cdf0e10cSrcweir     }
1893cdf0e10cSrcweir }
1894cdf0e10cSrcweir 
1895cdf0e10cSrcweir 
1896cdf0e10cSrcweir 
createTemporarySimpleRegistry(const Reference<XMultiComponentFactory> & rSMgr,const Reference<XComponentContext> & xCtx)1897cdf0e10cSrcweir Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1898cdf0e10cSrcweir 	const Reference< XMultiComponentFactory > &rSMgr,
1899cdf0e10cSrcweir 	const Reference < XComponentContext > & xCtx)
1900cdf0e10cSrcweir {
1901cdf0e10cSrcweir 
1902cdf0e10cSrcweir 	Reference < XSimpleRegistry > xReg(
1903cdf0e10cSrcweir 		rSMgr->createInstanceWithContext(
1904cdf0e10cSrcweir 			spool().com_sun_star_registry_SimpleRegistry,	xCtx ),
1905cdf0e10cSrcweir         UNO_QUERY);
1906cdf0e10cSrcweir 	OSL_ASSERT( xReg.is() );
1907cdf0e10cSrcweir 	return xReg;
1908cdf0e10cSrcweir }
1909cdf0e10cSrcweir }
1910cdf0e10cSrcweir 
1911cdf0e10cSrcweir namespace stoc_bootstrap
1912cdf0e10cSrcweir {
1913cdf0e10cSrcweir //*************************************************************************
ImplementationRegistration_CreateInstance(const Reference<XComponentContext> & xCtx)1914cdf0e10cSrcweir Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance(
1915cdf0e10cSrcweir     const Reference<XComponentContext> & xCtx ) // throw(Exception)
1916cdf0e10cSrcweir {
1917cdf0e10cSrcweir 	return (XImplementationRegistration *)new stoc_impreg::ImplementationRegistration(xCtx);
1918cdf0e10cSrcweir }
1919cdf0e10cSrcweir 
1920cdf0e10cSrcweir }
1921cdf0e10cSrcweir 
1922