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