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