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 114 : 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 114 : 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 114 : , Registry( RTL_CONSTASCII_USTRINGPARAM("Registry") )
106 114 : {}
107 : private:
108 : StringPool( const StringPool & );
109 : };
110 :
111 1718 : const StringPool &spool()
112 : {
113 : static StringPool *pPool = 0;
114 1718 : if( ! pPool )
115 : {
116 114 : MutexGuard guard( Mutex::getGlobalMutex() );
117 114 : if( ! pPool )
118 : {
119 114 : static StringPool pool;
120 114 : pPool = &pool;
121 114 : }
122 : }
123 1718 : return *pPool;
124 : }
125 : }
126 :
127 : extern rtl_StandardModuleCount g_moduleCount;
128 :
129 : namespace stoc_bootstrap
130 : {
131 122 : Sequence< OUString > impreg_getSupportedServiceNames()
132 : {
133 122 : Sequence< OUString > seqNames(1);
134 122 : seqNames.getArray()[0] = stoc_impreg::spool().sServiceName;
135 122 : return seqNames;
136 : }
137 :
138 1596 : OUString impreg_getImplementationName()
139 : {
140 1596 : return stoc_impreg::spool().sImplementationName;
141 : }
142 : }
143 :
144 : namespace stoc_impreg
145 : {
146 : //*************************************************************************
147 : // static deleteAllLinkReferences()
148 : //
149 0 : static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
150 : const Reference < XRegistryKey >& xSource)
151 : // throw ( InvalidRegistryException, RuntimeException )
152 : {
153 0 : Reference < XRegistryKey > xKey = xSource->openKey(
154 0 : spool().slash_UNO_slash_REGISTRY_LINKS );
155 :
156 0 : 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 0 : }
227 0 : }
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 0 : static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
361 : const OUString& value)
362 : // throw ( InvalidRegistryException, RuntimeException )
363 : {
364 0 : if (xSuperKey.is())
365 : {
366 : // try
367 : // {
368 0 : 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 0 : Sequence<OUString> implEntriesNew(1);
406 :
407 0 : implEntriesNew.getArray()[0] = value;
408 :
409 0 : xSuperKey->setAsciiListValue(implEntriesNew);
410 : }
411 : // }
412 : // catch(InvalidRegistryException&)
413 : // {
414 : // }
415 : }
416 0 : }
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 0 : 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 0 : Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
710 :
711 0 : if (subKeys.getLength() > 0)
712 : {
713 0 : const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
714 0 : Reference < XRegistryKey > xImplKey;
715 0 : sal_Bool hasLocationUrl = sal_False;
716 :
717 0 : const StringPool &pool = spool();
718 0 : for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
719 : {
720 0 : xImplKey = pSubKeys[i];
721 0 : Reference < XRegistryKey > xKey = xImplKey->openKey(
722 0 : pool.slash_UNO_slash_LOCATION );
723 :
724 0 : if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
725 : {
726 0 : if (xKey->getAsciiValue() == locationUrl)
727 : {
728 0 : hasLocationUrl = sal_True;
729 :
730 0 : OUString implName(xImplKey->getKeyName().getStr() + 1);
731 0 : sal_Int32 firstDot = implName.indexOf('/');
732 :
733 0 : if (firstDot >= 0)
734 0 : implName = implName.copy(firstDot + 1);
735 :
736 0 : implNames.push_back(implName);
737 :
738 0 : deleteAllLinkReferences(xReg, xImplKey);
739 :
740 0 : xKey = xImplKey->openKey( pool.slash_UNO );
741 0 : if (xKey.is())
742 : {
743 0 : Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
744 :
745 0 : if (subKeys2.getLength())
746 : {
747 0 : const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
748 :
749 0 : for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
750 : {
751 0 : if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
752 0 : pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
753 0 : pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
754 0 : pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
755 0 : pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
756 : {
757 0 : prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, sal_False);
758 : }
759 : }
760 0 : }
761 0 : }
762 : }
763 : }
764 :
765 0 : if (hasLocationUrl)
766 : {
767 0 : hasLocationUrl = sal_False;
768 0 : rtl::OUString path(xImplKey->getKeyName());
769 0 : xImplKey->closeKey();
770 0 : xReg->getRootKey()->deleteKey(path);
771 : }
772 0 : }
773 :
774 0 : subKeys = xSource->openKeys();
775 0 : if (subKeys.getLength() == 0)
776 : {
777 0 : rtl::OUString path(xSource->getKeyName());
778 0 : xSource->closeKey();
779 0 : xReg->getRootKey()->deleteKey(path);
780 0 : }
781 : } else
782 : {
783 0 : rtl::OUString path(xSource->getKeyName());
784 0 : xSource->closeKey();
785 0 : xReg->getRootKey()->deleteKey(path);
786 0 : }
787 0 : }
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 0 : 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 0 : Reference< registry::XRegistryKey > xKey( xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
958 0 : 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 0 : 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 0 : 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 0 : 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 0 : }
1073 0 : }
1074 :
1075 :
1076 : //*************************************************************************
1077 : // static prepareRegistry
1078 : //
1079 0 : 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 0 : Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
1088 :
1089 0 : if (!subKeys.getLength())
1090 : {
1091 : throw InvalidRegistryException(
1092 : OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): source registry is empty" ) ),
1093 0 : Reference< XInterface > () );
1094 : }
1095 :
1096 0 : const StringPool & pool = spool();
1097 :
1098 0 : const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
1099 0 : Reference < XRegistryKey > xImplKey;
1100 :
1101 0 : for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
1102 : {
1103 0 : xImplKey = pSubKeys[i];
1104 :
1105 0 : Reference < XRegistryKey > xKey = xImplKey->openKey(
1106 0 : pool.slash_UNO_slash_SERVICES );
1107 :
1108 0 : if (xKey.is())
1109 : {
1110 : // update entries in SERVICES section
1111 0 : Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
1112 0 : const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
1113 :
1114 0 : OUString implName = OUString(xImplKey->getKeyName().getStr() + 1);
1115 0 : sal_Int32 firstDot = implName.indexOf('/');
1116 :
1117 0 : if (firstDot >= 0)
1118 0 : implName = implName.copy(firstDot + 1);
1119 :
1120 0 : sal_Int32 offset = xKey->getKeyName().getLength() + 1;
1121 :
1122 0 : for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
1123 : {
1124 0 : OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
1125 :
1126 : createUniqueSubEntry(
1127 0 : xDest->getRootKey()->createKey(
1128 0 : pool.slash_SERVICES + serviceName ),
1129 0 : implName);
1130 0 : }
1131 :
1132 0 : xKey = xImplKey->openKey( pool.slash_UNO );
1133 0 : if (xKey.is())
1134 : {
1135 0 : Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
1136 :
1137 0 : if (subKeys2.getLength())
1138 : {
1139 0 : const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
1140 :
1141 0 : for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
1142 : {
1143 0 : if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
1144 0 : pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
1145 0 : pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
1146 : {
1147 0 : prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, sal_True);
1148 : }
1149 : }
1150 0 : }
1151 0 : }
1152 : }
1153 :
1154 : // update LOCATION entry
1155 0 : xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
1156 :
1157 0 : if (xKey.is())
1158 : {
1159 0 : xKey->setAsciiValue(locationUrl);
1160 : }
1161 :
1162 : // update ACTIVATOR entry
1163 0 : xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
1164 :
1165 0 : if (xKey.is())
1166 : {
1167 0 : xKey->setAsciiValue(implementationLoaderUrl);
1168 : }
1169 :
1170 0 : xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
1171 :
1172 0 : 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 0 : insert_singletons( xDest, xImplKey, xContext );
1189 0 : }
1190 0 : }
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 0 : ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
1325 0 : : m_xSMgr( xCtx->getServiceManager() )
1326 0 : , m_xCtx( xCtx )
1327 : {
1328 0 : g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
1329 0 : }
1330 :
1331 : //*************************************************************************
1332 : // ~ImplementationRegistration()
1333 : //
1334 0 : ImplementationRegistration::~ImplementationRegistration()
1335 : {
1336 0 : g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
1337 0 : }
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 0 : 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 0 : OUString implLoaderUrl(implementationLoaderUrl);
1506 0 : OUString activatorName;
1507 :
1508 0 : if (!implementationLoaderUrl.isEmpty())
1509 : {
1510 0 : OUString tmpActivator(implementationLoaderUrl);
1511 0 : sal_Int32 nIndex = 0;
1512 0 : 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 0 : if( m_xSMgr.is() ) {
1520 : try
1521 : {
1522 : Reference < XImplementationLoader > xAct(
1523 0 : m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
1524 0 : if (xAct.is())
1525 : {
1526 0 : Reference < XSimpleRegistry > xRegistry;
1527 :
1528 0 : if (xReg.is())
1529 : {
1530 : // registry supplied by user
1531 0 : xRegistry = xReg;
1532 : }
1533 : else
1534 : {
1535 0 : xRegistry = getRegistryFromServiceManager();
1536 : }
1537 :
1538 0 : if ( xRegistry.is())
1539 : {
1540 : doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implLoaderUrl,
1541 0 : locationUrl, registeredLocationUrl);
1542 0 : }
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 0 : }
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 0 : }
1589 0 : }
1590 :
1591 : //*************************************************************************
1592 : // virtual function registerImplementation of XImplementationRegistration
1593 : //
1594 0 : void ImplementationRegistration::registerImplementation(
1595 : const OUString& implementationLoaderUrl,
1596 : const OUString& locationUrl,
1597 : const Reference < XSimpleRegistry > & xReg)
1598 : throw( CannotRegisterImplementationException, RuntimeException )
1599 : {
1600 0 : prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
1601 0 : }
1602 :
1603 :
1604 : //*************************************************************************
1605 : // virtual function revokeImplementation of XImplementationRegistration
1606 : //
1607 0 : sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
1608 : const Reference < XSimpleRegistry >& xReg)
1609 : throw ( RuntimeException )
1610 : {
1611 0 : sal_Bool ret = sal_False;
1612 :
1613 0 : Reference < XSimpleRegistry > xRegistry;
1614 :
1615 0 : if (xReg.is()) {
1616 0 : 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 0 : if (xRegistry.is())
1635 : {
1636 : try
1637 : {
1638 0 : doRevoke(xRegistry, location);
1639 0 : 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 0 : 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 activatorName;
1661 :
1662 0 : if (!implementationLoaderUrl.isEmpty())
1663 : {
1664 0 : OUString tmpActivator(implementationLoaderUrl);
1665 0 : sal_Int32 nIndex = 0;
1666 0 : activatorName = tmpActivator.getToken(0, ':', nIndex );
1667 : } else
1668 : {
1669 : // check locationUrl to find out what kind of loader is needed
1670 : // set implementationLoaderUrl
1671 : }
1672 :
1673 0 : if( m_xSMgr.is() ) {
1674 :
1675 : Reference < XImplementationLoader > xAct(
1676 0 : m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
1677 :
1678 0 : if (xAct.is())
1679 : {
1680 :
1681 : Reference < XSimpleRegistry > xReg =
1682 0 : createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
1683 :
1684 0 : if (xReg.is())
1685 : {
1686 : try
1687 : {
1688 0 : xReg->open(OUString() /* in mem */, sal_False, sal_True);
1689 0 : Reference < XRegistryKey > xImpl;
1690 :
1691 : { // only necessary for deleting the temporary variable of rootkey
1692 0 : xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1693 : }
1694 0 : if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
1695 : {
1696 0 : std::list <OUString> implNames;
1697 :
1698 0 : findImplementations(xImpl, implNames);
1699 :
1700 0 : if (!implNames.empty())
1701 : {
1702 0 : std::list<OUString>::const_iterator iter = implNames.begin();
1703 :
1704 0 : Sequence<OUString> seqImpl(implNames.size());
1705 0 : OUString *pImplNames = seqImpl.getArray();
1706 :
1707 0 : sal_Int32 index = 0;
1708 0 : while (iter != implNames.end())
1709 : {
1710 0 : pImplNames[index] = *iter;
1711 0 : index++;
1712 0 : ++iter;
1713 : }
1714 :
1715 0 : xImpl->closeKey();
1716 0 : return seqImpl;
1717 0 : }
1718 : }
1719 :
1720 0 : xImpl->closeKey();
1721 : }
1722 0 : catch(MergeConflictException&)
1723 : {
1724 : }
1725 0 : catch(InvalidRegistryException&)
1726 : {
1727 : }
1728 0 : }
1729 0 : }
1730 : }
1731 :
1732 0 : return Sequence<OUString>();
1733 : }
1734 :
1735 : //*************************************************************************
1736 : // virtual function checkInstantiation of XImplementationRegistration
1737 : //
1738 0 : Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
1739 : throw ( RuntimeException )
1740 : {
1741 : OSL_FAIL( "ImplementationRegistration::checkInstantiation not implemented" );
1742 0 : return Sequence<OUString>();
1743 : }
1744 :
1745 : //*************************************************************************
1746 : // helper function doRegistration
1747 : //
1748 :
1749 0 : void ImplementationRegistration::doRevoke(
1750 : const Reference < XSimpleRegistry >& xDest,
1751 : const OUString& locationUrl)
1752 : // throw ( InvalidRegistryException, RuntimeException )
1753 : {
1754 0 : if( xDest.is() )
1755 : {
1756 0 : std::list<OUString> aNames;
1757 :
1758 0 : const StringPool &pool = spool();
1759 0 : Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
1760 :
1761 : Reference < XRegistryKey > xKey =
1762 0 : xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
1763 0 : if (xKey.is() && xKey->isValid())
1764 : {
1765 0 : deleteAllImplementations(xDest, xKey, locationUrl, aNames);
1766 : }
1767 :
1768 0 : xKey = xRootKey->openKey( pool.slash_SERVICES );
1769 0 : if (xKey.is())
1770 : {
1771 0 : std::list<OUString>::const_iterator iter = aNames.begin();
1772 :
1773 0 : while (iter != aNames.end())
1774 : {
1775 0 : deleteAllServiceEntries(xDest, xKey, *iter);
1776 0 : ++iter;
1777 : }
1778 : }
1779 :
1780 0 : xKey = xRootKey->openKey( OUSTR("/SINGLETONS") );
1781 0 : if (xKey.is() && xKey->isValid())
1782 : {
1783 0 : delete_all_singleton_entries( xKey, aNames );
1784 : }
1785 :
1786 0 : if (xRootKey.is())
1787 0 : xRootKey->closeKey();
1788 0 : if (xKey.is() && xKey->isValid() )
1789 0 : xKey->closeKey();
1790 : }
1791 0 : }
1792 :
1793 0 : void ImplementationRegistration::doRegister(
1794 : const Reference< XMultiComponentFactory > & xSMgr,
1795 : const Reference< XComponentContext > &xCtx,
1796 : const Reference < XImplementationLoader > & xAct,
1797 : const Reference < XSimpleRegistry >& xDest,
1798 : const OUString& implementationLoaderUrl,
1799 : const OUString& locationUrl,
1800 : const OUString& registeredLocationUrl)
1801 : /* throw ( InvalidRegistryException,
1802 : MergeConflictException,
1803 : CannotRegisterImplementationException, RuntimeException ) */
1804 : {
1805 : Reference < XSimpleRegistry > xReg =
1806 0 : createTemporarySimpleRegistry( xSMgr, xCtx );
1807 0 : Reference < XRegistryKey > xSourceKey;
1808 :
1809 0 : if (xAct.is() && xReg.is() && xDest.is())
1810 : {
1811 : try
1812 : {
1813 0 : xReg->open(OUString() /* in mem */, sal_False, sal_True);
1814 :
1815 : { // only necessary for deleting the temporary variable of rootkey
1816 0 : xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
1817 : }
1818 :
1819 : sal_Bool bSuccess =
1820 0 : xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
1821 0 : if ( bSuccess )
1822 : {
1823 0 : prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
1824 :
1825 0 : xSourceKey->closeKey();
1826 :
1827 0 : xSourceKey = xReg->getRootKey();
1828 0 : Reference < XRegistryKey > xDestKey = xDest->getRootKey();
1829 0 : mergeKeys( xDestKey, xSourceKey );
1830 0 : xDestKey->closeKey();
1831 0 : xSourceKey->closeKey();
1832 : }
1833 : else
1834 : {
1835 : throw CannotRegisterImplementationException(
1836 : OUString( RTL_CONSTASCII_USTRINGPARAM( "ImplementationRegistration::doRegistration() component registration signaled failure" ) ),
1837 0 : Reference< XInterface > () );
1838 : }
1839 :
1840 : // Cleanup Source registry.
1841 0 : if ( xSourceKey->isValid() )
1842 0 : xSourceKey->closeKey();
1843 : }
1844 0 : catch(CannotRegisterImplementationException&)
1845 : {
1846 0 : if ( xSourceKey->isValid() )
1847 0 : xSourceKey->closeKey();
1848 : // and throw again
1849 0 : throw;
1850 : }
1851 0 : }
1852 0 : }
1853 :
1854 :
1855 :
1856 0 : Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
1857 : const Reference< XMultiComponentFactory > &rSMgr,
1858 : const Reference < XComponentContext > & xCtx)
1859 : {
1860 :
1861 : Reference < XSimpleRegistry > xReg(
1862 0 : rSMgr->createInstanceWithContext(
1863 0 : spool().com_sun_star_registry_SimpleRegistry, xCtx ),
1864 0 : UNO_QUERY);
1865 : OSL_ASSERT( xReg.is() );
1866 0 : return xReg;
1867 : }
1868 : }
1869 :
1870 : namespace stoc_bootstrap
1871 : {
1872 : //*************************************************************************
1873 0 : Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance(
1874 : const Reference<XComponentContext> & xCtx ) // throw(Exception)
1875 : {
1876 0 : return (XImplementationRegistration *)new stoc_impreg::ImplementationRegistration(xCtx);
1877 : }
1878 :
1879 : }
1880 :
1881 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|