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