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