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