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_desktop.hxx" 30 31 #include "dp_component.hrc" 32 #include "dp_backend.h" 33 #include "dp_platform.hxx" 34 #include "dp_ucb.h" 35 #include "rtl/string.hxx" 36 #include "rtl/strbuf.hxx" 37 #include "rtl/ustrbuf.hxx" 38 #include "rtl/uri.hxx" 39 #include "cppuhelper/exc_hlp.hxx" 40 #include "ucbhelper/content.hxx" 41 #include "comphelper/anytostring.hxx" 42 #include "comphelper/servicedecl.hxx" 43 #include "comphelper/sequence.hxx" 44 #include "xmlscript/xml_helper.hxx" 45 #include "svl/inettype.hxx" 46 #include "com/sun/star/lang/WrappedTargetRuntimeException.hpp" 47 #include "com/sun/star/container/XNameContainer.hpp" 48 #include "com/sun/star/container/XHierarchicalNameAccess.hpp" 49 #include "com/sun/star/container/XSet.hpp" 50 #include "com/sun/star/registry/XSimpleRegistry.hpp" 51 #include "com/sun/star/registry/XImplementationRegistration.hpp" 52 #include "com/sun/star/loader/XImplementationLoader.hpp" 53 #include "com/sun/star/io/XInputStream.hpp" 54 #include "com/sun/star/ucb/NameClash.hpp" 55 #include "com/sun/star/util/XMacroExpander.hpp" 56 #include <list> 57 #include <hash_map> 58 #include <vector> 59 #include <memory> 60 #include <algorithm> 61 #include "dp_compbackenddb.hxx" 62 63 using namespace ::dp_misc; 64 using namespace ::com::sun::star; 65 using namespace ::com::sun::star::uno; 66 using namespace ::com::sun::star::ucb; 67 using ::rtl::OUString; 68 namespace css = com::sun::star; 69 70 namespace dp_registry { 71 namespace backend { 72 namespace component { 73 namespace { 74 75 typedef ::std::list<OUString> t_stringlist; 76 typedef ::std::vector< ::std::pair<OUString, OUString> > t_stringpairvec; 77 78 #define IMPLEMENTATION_NAME "com.sun.star.comp.deployment.component.PackageRegistryBackend" 79 80 /** return a vector of bootstrap variables which have been provided 81 as command arguments. 82 */ 83 ::std::vector<OUString> getCmdBootstrapVariables() 84 { 85 ::std::vector<OUString> ret; 86 sal_uInt32 count = osl_getCommandArgCount(); 87 for (sal_uInt32 i = 0; i < count; i++) 88 { 89 OUString arg; 90 osl_getCommandArg(i, &arg.pData); 91 if (arg.matchAsciiL("-env:", 5)) 92 ret.push_back(arg); 93 } 94 return ret; 95 } 96 97 bool jarManifestHeaderPresent( 98 OUString const & url, OUString const & name, 99 Reference<XCommandEnvironment> const & xCmdEnv ) 100 { 101 ::rtl::OUStringBuffer buf; 102 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.zip://") ); 103 buf.append( 104 ::rtl::Uri::encode( 105 url, rtl_UriCharClassRegName, rtl_UriEncodeIgnoreEscapes, 106 RTL_TEXTENCODING_UTF8 ) ); 107 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/META-INF/MANIFEST.MF") ); 108 ::ucbhelper::Content manifestContent; 109 OUString line; 110 return 111 create_ucb_content( 112 &manifestContent, buf.makeStringAndClear(), xCmdEnv, 113 false /* no throw */ ) 114 && readLine( &line, name, manifestContent, RTL_TEXTENCODING_ASCII_US ); 115 } 116 117 //============================================================================== 118 class BackendImpl : public ::dp_registry::backend::PackageRegistryBackend 119 { 120 class ComponentPackageImpl : public ::dp_registry::backend::Package 121 { 122 BackendImpl * getMyBackend() const; 123 124 const OUString m_loader; 125 126 enum reg { 127 REG_UNINIT, REG_VOID, REG_REGISTERED, REG_NOT_REGISTERED, REG_MAYBE_REGISTERED 128 } m_registered; 129 130 void getComponentInfo( 131 ComponentBackendDb::Data * data, 132 std::vector< css::uno::Reference< css::uno::XInterface > > * 133 factories, 134 Reference<XComponentContext> const & xContext ); 135 136 virtual void SAL_CALL disposing(); 137 138 // Package 139 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( 140 ::osl::ResettableMutexGuard & guard, 141 ::rtl::Reference<AbortChannel> const & abortChannel, 142 Reference<XCommandEnvironment> const & xCmdEnv ); 143 virtual void processPackage_( 144 ::osl::ResettableMutexGuard & guard, 145 bool registerPackage, 146 bool startup, 147 ::rtl::Reference<AbortChannel> const & abortChannel, 148 Reference<XCommandEnvironment> const & xCmdEnv ); 149 150 const Reference<registry::XSimpleRegistry> getRDB() const; 151 152 //Provides the read-only registry (e.g. not the one based on the duplicated 153 //rdb files 154 const Reference<registry::XSimpleRegistry> getRDB_RO() const; 155 156 public: 157 ComponentPackageImpl( 158 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 159 OUString const & url, OUString const & name, 160 Reference<deployment::XPackageTypeInfo> const & xPackageType, 161 OUString const & loader, bool bRemoved, 162 OUString const & identifier); 163 }; 164 friend class ComponentPackageImpl; 165 166 class ComponentsPackageImpl : public ::dp_registry::backend::Package 167 { 168 BackendImpl * getMyBackend() const; 169 170 // Package 171 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( 172 ::osl::ResettableMutexGuard & guard, 173 ::rtl::Reference<AbortChannel> const & abortChannel, 174 Reference<XCommandEnvironment> const & xCmdEnv ); 175 virtual void processPackage_( 176 ::osl::ResettableMutexGuard & guard, 177 bool registerPackage, 178 bool startup, 179 ::rtl::Reference<AbortChannel> const & abortChannel, 180 Reference<XCommandEnvironment> const & xCmdEnv ); 181 public: 182 ComponentsPackageImpl( 183 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 184 OUString const & url, OUString const & name, 185 Reference<deployment::XPackageTypeInfo> const & xPackageType, 186 bool bRemoved, OUString const & identifier); 187 }; 188 friend class ComponentsPackageImpl; 189 190 class TypelibraryPackageImpl : public ::dp_registry::backend::Package 191 { 192 BackendImpl * getMyBackend() const; 193 194 const bool m_jarFile; 195 Reference<container::XHierarchicalNameAccess> m_xTDprov; 196 197 virtual void SAL_CALL disposing(); 198 199 // Package 200 virtual beans::Optional< beans::Ambiguous<sal_Bool> > isRegistered_( 201 ::osl::ResettableMutexGuard & guard, 202 ::rtl::Reference<AbortChannel> const & abortChannel, 203 Reference<XCommandEnvironment> const & xCmdEnv ); 204 virtual void processPackage_( 205 ::osl::ResettableMutexGuard & guard, 206 bool registerPackage, 207 bool startup, 208 ::rtl::Reference<AbortChannel> const & abortChannel, 209 Reference<XCommandEnvironment> const & xCmdEnv ); 210 211 public: 212 TypelibraryPackageImpl( 213 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 214 OUString const & url, OUString const & name, 215 Reference<deployment::XPackageTypeInfo> const & xPackageType, 216 bool jarFile, bool bRemoved, 217 OUString const & identifier); 218 }; 219 friend class TypelibraryPackageImpl; 220 221 t_stringlist m_jar_typelibs; 222 t_stringlist m_rdb_typelibs; 223 t_stringlist m_components; 224 225 enum RcItem { RCITEM_JAR_TYPELIB, RCITEM_RDB_TYPELIB, RCITEM_COMPONENTS }; 226 227 t_stringlist & getRcItemList( RcItem kind ) { 228 switch (kind) 229 { 230 case RCITEM_JAR_TYPELIB: 231 return m_jar_typelibs; 232 case RCITEM_RDB_TYPELIB: 233 return m_rdb_typelibs; 234 default: // case RCITEM_COMPONENTS 235 return m_components; 236 } 237 } 238 239 bool m_unorc_inited; 240 bool m_unorc_modified; 241 bool bSwitchedRdbFiles; 242 243 typedef ::std::hash_map< OUString, Reference<XInterface>, 244 ::rtl::OUStringHash > t_string2object; 245 t_string2object m_backendObjects; 246 247 // PackageRegistryBackend 248 virtual Reference<deployment::XPackage> bindPackage_( 249 OUString const & url, OUString const & mediaType, 250 sal_Bool bRemoved, OUString const & identifier, 251 Reference<XCommandEnvironment> const & xCmdEnv ); 252 253 virtual void SAL_CALL disposing(); 254 255 const Reference<deployment::XPackageTypeInfo> m_xDynComponentTypeInfo; 256 const Reference<deployment::XPackageTypeInfo> m_xJavaComponentTypeInfo; 257 const Reference<deployment::XPackageTypeInfo> m_xPythonComponentTypeInfo; 258 const Reference<deployment::XPackageTypeInfo> m_xComponentsTypeInfo; 259 const Reference<deployment::XPackageTypeInfo> m_xRDBTypelibTypeInfo; 260 const Reference<deployment::XPackageTypeInfo> m_xJavaTypelibTypeInfo; 261 Sequence< Reference<deployment::XPackageTypeInfo> > m_typeInfos; 262 263 OUString m_commonRDB; 264 OUString m_nativeRDB; 265 266 //URLs of the read-only rdbs (e.g. not the ones of the duplicated files) 267 OUString m_commonRDB_RO; 268 OUString m_nativeRDB_RO; 269 270 std::auto_ptr<ComponentBackendDb> m_backendDb; 271 272 void addDataToDb(OUString const & url, ComponentBackendDb::Data const & data); 273 ComponentBackendDb::Data readDataFromDb(OUString const & url); 274 void revokeEntryFromDb(OUString const & url); 275 276 277 //These rdbs are for writing new service entries. The rdb files are copies 278 //which are created when services are added or removed. 279 Reference<registry::XSimpleRegistry> m_xCommonRDB; 280 Reference<registry::XSimpleRegistry> m_xNativeRDB; 281 282 //These rdbs are created on the read-only rdbs which are already used 283 //by UNO since the startup of the current session. 284 Reference<registry::XSimpleRegistry> m_xCommonRDB_RO; 285 Reference<registry::XSimpleRegistry> m_xNativeRDB_RO; 286 287 288 void unorc_verify_init( Reference<XCommandEnvironment> const & xCmdEnv ); 289 void unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv ); 290 291 Reference<XInterface> getObject( OUString const & id ); 292 Reference<XInterface> insertObject( 293 OUString const & id, Reference<XInterface> const & xObject ); 294 void releaseObject( OUString const & id ); 295 296 bool addToUnoRc( RcItem kind, OUString const & url, 297 Reference<XCommandEnvironment> const & xCmdEnv ); 298 bool removeFromUnoRc( RcItem kind, OUString const & url, 299 Reference<XCommandEnvironment> const & xCmdEnv ); 300 bool hasInUnoRc( RcItem kind, OUString const & url ); 301 302 css::uno::Reference< css::registry::XRegistryKey > openRegistryKey( 303 css::uno::Reference< css::registry::XRegistryKey > const & base, 304 rtl::OUString const & path); 305 306 void extractComponentData( 307 css::uno::Reference< css::uno::XComponentContext > const & context, 308 css::uno::Reference< css::registry::XRegistryKey > const & registry, 309 ComponentBackendDb::Data * data, 310 std::vector< css::uno::Reference< css::uno::XInterface > > * factories, 311 css::uno::Reference< css::loader::XImplementationLoader > const * 312 componentLoader, 313 rtl::OUString const * componentUrl); 314 315 void componentLiveInsertion( 316 ComponentBackendDb::Data const & data, 317 std::vector< css::uno::Reference< css::uno::XInterface > > const & 318 factories); 319 320 void componentLiveRemoval(ComponentBackendDb::Data const & data); 321 322 public: 323 BackendImpl( Sequence<Any> const & args, 324 Reference<XComponentContext> const & xComponentContext ); 325 326 // XPackageRegistry 327 virtual Sequence< Reference<deployment::XPackageTypeInfo> > SAL_CALL 328 getSupportedPackageTypes() throw (RuntimeException); 329 330 virtual void SAL_CALL packageRemoved(OUString const & url, OUString const & mediaType) 331 throw (deployment::DeploymentException, 332 uno::RuntimeException); 333 334 using PackageRegistryBackend::disposing; 335 336 //Will be called from ComponentPackageImpl 337 void initServiceRdbFiles(); 338 339 //Creates the READ ONLY registries (m_xCommonRDB_RO,m_xNativeRDB_RO) 340 void initServiceRdbFiles_RO(); 341 }; 342 343 //______________________________________________________________________________ 344 345 BackendImpl::ComponentPackageImpl::ComponentPackageImpl( 346 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 347 OUString const & url, OUString const & name, 348 Reference<deployment::XPackageTypeInfo> const & xPackageType, 349 OUString const & loader, bool bRemoved, 350 OUString const & identifier) 351 : Package( myBackend, url, name, name /* display-name */, 352 xPackageType, bRemoved, identifier), 353 m_loader( loader ), 354 m_registered( REG_UNINIT ) 355 {} 356 357 const Reference<registry::XSimpleRegistry> 358 BackendImpl::ComponentPackageImpl::getRDB() const 359 { 360 BackendImpl * that = getMyBackend(); 361 362 //Late "initialization" of the services rdb files 363 //This is to prevent problems when running several 364 //instances of OOo with root rights in parallel. This 365 //would otherwise cause problems when copying the rdbs. 366 //See http://qa.openoffice.org/issues/show_bug.cgi?id=99257 367 { 368 const ::osl::MutexGuard guard( getMutex() ); 369 if (!that->bSwitchedRdbFiles) 370 { 371 that->bSwitchedRdbFiles = true; 372 that->initServiceRdbFiles(); 373 } 374 } 375 if (m_loader.equalsAsciiL( 376 RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") )) 377 return that->m_xNativeRDB; 378 else 379 return that->m_xCommonRDB; 380 } 381 382 //Returns the read only RDB. 383 const Reference<registry::XSimpleRegistry> 384 BackendImpl::ComponentPackageImpl::getRDB_RO() const 385 { 386 BackendImpl * that = getMyBackend(); 387 388 if (m_loader.equalsAsciiL( 389 RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.SharedLibrary") )) 390 return that->m_xNativeRDB_RO; 391 else 392 return that->m_xCommonRDB_RO; 393 } 394 395 BackendImpl * BackendImpl::ComponentPackageImpl::getMyBackend() const 396 { 397 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); 398 if (NULL == pBackend) 399 { 400 //Throws a DisposedException 401 check(); 402 //We should never get here... 403 throw RuntimeException( 404 OUSTR("Failed to get the BackendImpl"), 405 static_cast<OWeakObject*>(const_cast<ComponentPackageImpl *>(this))); 406 } 407 return pBackend; 408 } 409 410 411 //______________________________________________________________________________ 412 void BackendImpl::ComponentPackageImpl::disposing() 413 { 414 // m_xRemoteContext.clear(); 415 Package::disposing(); 416 } 417 418 //______________________________________________________________________________ 419 void BackendImpl::TypelibraryPackageImpl::disposing() 420 { 421 m_xTDprov.clear(); 422 Package::disposing(); 423 } 424 425 //______________________________________________________________________________ 426 void BackendImpl::disposing() 427 { 428 try { 429 m_backendObjects = t_string2object(); 430 if (m_xNativeRDB.is()) { 431 m_xNativeRDB->close(); 432 m_xNativeRDB.clear(); 433 } 434 if (m_xCommonRDB.is()) { 435 m_xCommonRDB->close(); 436 m_xCommonRDB.clear(); 437 } 438 unorc_flush( Reference<XCommandEnvironment>() ); 439 440 PackageRegistryBackend::disposing(); 441 } 442 catch (RuntimeException &) { 443 throw; 444 } 445 catch (Exception &) { 446 Any exc( ::cppu::getCaughtException() ); 447 throw lang::WrappedTargetRuntimeException( 448 OUSTR("caught unexpected exception while disposing..."), 449 static_cast<OWeakObject *>(this), exc ); 450 } 451 } 452 453 454 void BackendImpl::initServiceRdbFiles() 455 { 456 const Reference<XCommandEnvironment> xCmdEnv; 457 458 ::ucbhelper::Content cacheDir( getCachePath(), xCmdEnv ); 459 ::ucbhelper::Content oldRDB; 460 // switch common rdb: 461 if (m_commonRDB_RO.getLength() > 0) 462 { 463 create_ucb_content( 464 &oldRDB, makeURL( getCachePath(), m_commonRDB_RO), 465 xCmdEnv, false /* no throw */ ); 466 } 467 m_commonRDB = m_commonRDB_RO.equalsAsciiL( 468 RTL_CONSTASCII_STRINGPARAM("common.rdb") ) 469 ? OUSTR("common_.rdb") : OUSTR("common.rdb"); 470 if (oldRDB.get().is()) 471 { 472 if (! cacheDir.transferContent( 473 oldRDB, ::ucbhelper::InsertOperation_COPY, 474 m_commonRDB, NameClash::OVERWRITE )) 475 { 476 477 throw RuntimeException( 478 OUSTR("UCB transferContent() failed!"), 0 ); 479 } 480 oldRDB = ::ucbhelper::Content(); 481 } 482 // switch native rdb: 483 if (m_nativeRDB_RO.getLength() > 0) 484 { 485 create_ucb_content( 486 &oldRDB, makeURL(getCachePath(), m_nativeRDB_RO), 487 xCmdEnv, false /* no throw */ ); 488 } 489 const OUString plt_rdb( getPlatformString() + OUSTR(".rdb") ); 490 const OUString plt_rdb_( getPlatformString() + OUSTR("_.rdb") ); 491 m_nativeRDB = m_nativeRDB_RO.equals( plt_rdb ) ? plt_rdb_ : plt_rdb; 492 if (oldRDB.get().is()) 493 { 494 if (! cacheDir.transferContent( 495 oldRDB, ::ucbhelper::InsertOperation_COPY, 496 m_nativeRDB, NameClash::OVERWRITE )) 497 throw RuntimeException( 498 OUSTR("UCB transferContent() failed!"), 0 ); 499 } 500 501 // UNO is bootstrapped, flush for next process start: 502 m_unorc_modified = true; 503 unorc_flush( Reference<XCommandEnvironment>() ); 504 505 506 // common rdb for java, native rdb for shared lib components 507 if (m_commonRDB.getLength() > 0) { 508 m_xCommonRDB.set( 509 m_xComponentContext->getServiceManager() 510 ->createInstanceWithContext( 511 OUSTR("com.sun.star.registry.SimpleRegistry"), 512 m_xComponentContext ), UNO_QUERY_THROW ); 513 m_xCommonRDB->open( 514 makeURL( expandUnoRcUrl(getCachePath()), m_commonRDB ), 515 // m_readOnly, !m_readOnly ); 516 false, true); 517 } 518 if (m_nativeRDB.getLength() > 0) { 519 m_xNativeRDB.set( 520 m_xComponentContext->getServiceManager() 521 ->createInstanceWithContext( 522 OUSTR("com.sun.star.registry.SimpleRegistry"), 523 m_xComponentContext ), UNO_QUERY_THROW ); 524 m_xNativeRDB->open( 525 makeURL( expandUnoRcUrl(getCachePath()), m_nativeRDB ), 526 // m_readOnly, !m_readOnly ); 527 false, true); 528 } 529 } 530 531 void BackendImpl::initServiceRdbFiles_RO() 532 { 533 const Reference<XCommandEnvironment> xCmdEnv; 534 535 // common rdb for java, native rdb for shared lib components 536 if (m_commonRDB_RO.getLength() > 0) 537 { 538 m_xCommonRDB_RO.set( 539 m_xComponentContext->getServiceManager() 540 ->createInstanceWithContext( 541 OUSTR("com.sun.star.registry.SimpleRegistry"), 542 m_xComponentContext), UNO_QUERY_THROW); 543 m_xCommonRDB_RO->open( 544 makeURL(expandUnoRcUrl(getCachePath()), m_commonRDB_RO), 545 sal_True, //read-only 546 sal_True); // create data source if necessary 547 } 548 if (m_nativeRDB_RO.getLength() > 0) 549 { 550 m_xNativeRDB_RO.set( 551 m_xComponentContext->getServiceManager() 552 ->createInstanceWithContext( 553 OUSTR("com.sun.star.registry.SimpleRegistry"), 554 m_xComponentContext), UNO_QUERY_THROW); 555 m_xNativeRDB_RO->open( 556 makeURL(expandUnoRcUrl(getCachePath()), m_nativeRDB_RO), 557 sal_True, //read-only 558 sal_True); // create data source if necessary 559 } 560 } 561 562 //______________________________________________________________________________ 563 BackendImpl::BackendImpl( 564 Sequence<Any> const & args, 565 Reference<XComponentContext> const & xComponentContext ) 566 : PackageRegistryBackend( args, xComponentContext ), 567 m_unorc_inited( false ), 568 m_unorc_modified( false ), 569 bSwitchedRdbFiles(false), 570 m_xDynComponentTypeInfo( new Package::TypeInfo( 571 OUSTR("application/" 572 "vnd.sun.star.uno-component;" 573 "type=native;platform=") + 574 getPlatformString(), 575 OUSTR("*" SAL_DLLEXTENSION), 576 getResourceString(RID_STR_DYN_COMPONENT), 577 RID_IMG_COMPONENT, 578 RID_IMG_COMPONENT_HC ) ), 579 m_xJavaComponentTypeInfo( new Package::TypeInfo( 580 OUSTR("application/" 581 "vnd.sun.star.uno-component;" 582 "type=Java"), 583 OUSTR("*.jar"), 584 getResourceString(RID_STR_JAVA_COMPONENT), 585 RID_IMG_JAVA_COMPONENT, 586 RID_IMG_JAVA_COMPONENT_HC ) ), 587 m_xPythonComponentTypeInfo( new Package::TypeInfo( 588 OUSTR("application/" 589 "vnd.sun.star.uno-component;" 590 "type=Python"), 591 OUSTR("*.py"), 592 getResourceString( 593 RID_STR_PYTHON_COMPONENT), 594 RID_IMG_COMPONENT, 595 RID_IMG_COMPONENT_HC ) ), 596 m_xComponentsTypeInfo( new Package::TypeInfo( 597 OUSTR("application/" 598 "vnd.sun.star.uno-components"), 599 OUSTR("*.components"), 600 getResourceString(RID_STR_COMPONENTS), 601 RID_IMG_COMPONENT, 602 RID_IMG_COMPONENT_HC ) ), 603 m_xRDBTypelibTypeInfo( new Package::TypeInfo( 604 OUSTR("application/" 605 "vnd.sun.star.uno-typelibrary;" 606 "type=RDB"), 607 OUSTR("*.rdb"), 608 getResourceString(RID_STR_RDB_TYPELIB), 609 RID_IMG_TYPELIB, RID_IMG_TYPELIB_HC ) ), 610 m_xJavaTypelibTypeInfo( new Package::TypeInfo( 611 OUSTR("application/" 612 "vnd.sun.star.uno-typelibrary;" 613 "type=Java"), 614 OUSTR("*.jar"), 615 getResourceString(RID_STR_JAVA_TYPELIB), 616 RID_IMG_JAVA_TYPELIB, 617 RID_IMG_JAVA_TYPELIB_HC ) ), 618 m_typeInfos( 6 ) 619 { 620 m_typeInfos[ 0 ] = m_xDynComponentTypeInfo; 621 m_typeInfos[ 1 ] = m_xJavaComponentTypeInfo; 622 m_typeInfos[ 2 ] = m_xPythonComponentTypeInfo; 623 m_typeInfos[ 3 ] = m_xComponentsTypeInfo; 624 m_typeInfos[ 4 ] = m_xRDBTypelibTypeInfo; 625 m_typeInfos[ 5 ] = m_xJavaTypelibTypeInfo; 626 627 const Reference<XCommandEnvironment> xCmdEnv; 628 629 if (transientMode()) 630 { 631 // in-mem rdbs: 632 // common rdb for java, native rdb for shared lib components 633 m_xCommonRDB.set( 634 xComponentContext->getServiceManager()->createInstanceWithContext( 635 OUSTR("com.sun.star.registry.SimpleRegistry"), 636 xComponentContext ), UNO_QUERY_THROW ); 637 m_xCommonRDB->open( OUString() /* in-mem */, 638 false /* ! read-only */, true /* create */ ); 639 m_xNativeRDB.set( 640 xComponentContext->getServiceManager()->createInstanceWithContext( 641 OUSTR("com.sun.star.registry.SimpleRegistry"), 642 xComponentContext ), UNO_QUERY_THROW ); 643 m_xNativeRDB->open( OUString() /* in-mem */, 644 false /* ! read-only */, true /* create */ ); 645 } 646 else 647 { 648 //do this before initServiceRdbFiles_RO, because it determines 649 //m_commonRDB and m_nativeRDB 650 unorc_verify_init( xCmdEnv ); 651 652 initServiceRdbFiles_RO(); 653 654 OUString dbFile = makeURL(getCachePath(), OUSTR("backenddb.xml")); 655 m_backendDb.reset( 656 new ComponentBackendDb(getComponentContext(), dbFile)); 657 } 658 } 659 660 void BackendImpl::addDataToDb( 661 OUString const & url, ComponentBackendDb::Data const & data) 662 { 663 if (m_backendDb.get()) 664 m_backendDb->addEntry(url, data); 665 } 666 667 ComponentBackendDb::Data BackendImpl::readDataFromDb(OUString const & url) 668 { 669 ComponentBackendDb::Data data; 670 if (m_backendDb.get()) 671 data = m_backendDb->getEntry(url); 672 return data; 673 } 674 675 void BackendImpl::revokeEntryFromDb(OUString const & url) 676 { 677 if (m_backendDb.get()) 678 m_backendDb->revokeEntry(url); 679 } 680 681 // XPackageRegistry 682 //______________________________________________________________________________ 683 Sequence< Reference<deployment::XPackageTypeInfo> > 684 BackendImpl::getSupportedPackageTypes() throw (RuntimeException) 685 { 686 return m_typeInfos; 687 } 688 689 void BackendImpl::packageRemoved(OUString const & url, OUString const & /*mediaType*/) 690 throw (deployment::DeploymentException, 691 uno::RuntimeException) 692 { 693 if (m_backendDb.get()) 694 m_backendDb->removeEntry(url); 695 } 696 697 // PackageRegistryBackend 698 //______________________________________________________________________________ 699 Reference<deployment::XPackage> BackendImpl::bindPackage_( 700 OUString const & url, OUString const & mediaType_, 701 sal_Bool bRemoved, OUString const & identifier, 702 Reference<XCommandEnvironment> const & xCmdEnv ) 703 { 704 OUString mediaType(mediaType_); 705 if (mediaType.getLength() == 0 || 706 mediaType.equalsAsciiL( 707 RTL_CONSTASCII_STRINGPARAM( 708 "application/vnd.sun.star.uno-component") ) || 709 mediaType.equalsAsciiL( 710 RTL_CONSTASCII_STRINGPARAM( 711 "application/vnd.sun.star.uno-typelibrary") )) 712 { 713 // detect exact media-type: 714 ::ucbhelper::Content ucbContent; 715 if (create_ucb_content( &ucbContent, url, xCmdEnv )) { 716 const OUString title( ucbContent.getPropertyValue( 717 StrTitle::get() ).get<OUString>() ); 718 if (title.endsWithIgnoreAsciiCaseAsciiL( 719 RTL_CONSTASCII_STRINGPARAM(SAL_DLLEXTENSION) )) 720 { 721 mediaType = OUSTR("application/vnd.sun.star.uno-component;" 722 "type=native;platform=") + 723 getPlatformString(); 724 } 725 else if (title.endsWithIgnoreAsciiCaseAsciiL( 726 RTL_CONSTASCII_STRINGPARAM(".jar") )) 727 { 728 if (jarManifestHeaderPresent( 729 url, OUSTR("RegistrationClassName"), xCmdEnv )) 730 mediaType = OUSTR( 731 "application/vnd.sun.star.uno-component;type=Java"); 732 if (mediaType.getLength() == 0) 733 mediaType = OUSTR( 734 "application/vnd.sun.star.uno-typelibrary;type=Java"); 735 } 736 else if (title.endsWithIgnoreAsciiCaseAsciiL( 737 RTL_CONSTASCII_STRINGPARAM(".py") )) 738 mediaType = 739 OUSTR("application/vnd.sun.star.uno-component;type=Python"); 740 else if (title.endsWithIgnoreAsciiCaseAsciiL( 741 RTL_CONSTASCII_STRINGPARAM(".rdb") )) 742 mediaType = 743 OUSTR("application/vnd.sun.star.uno-typelibrary;type=RDB"); 744 } 745 if (mediaType.getLength() == 0) 746 throw lang::IllegalArgumentException( 747 StrCannotDetectMediaType::get() + url, 748 static_cast<OWeakObject *>(this), static_cast<sal_Int16>(-1) ); 749 } 750 751 String type, subType; 752 INetContentTypeParameterList params; 753 if (INetContentTypes::parse( mediaType, type, subType, ¶ms )) 754 { 755 if (type.EqualsIgnoreCaseAscii("application")) 756 { 757 OUString name; 758 if (!bRemoved) 759 { 760 ::ucbhelper::Content ucbContent( url, xCmdEnv ); 761 name = ucbContent.getPropertyValue( 762 StrTitle::get() ).get<OUString>(); 763 } 764 765 if (subType.EqualsIgnoreCaseAscii("vnd.sun.star.uno-component")) 766 { 767 // xxx todo: probe and evaluate component xml description 768 769 INetContentTypeParameter const * param = params.find( 770 ByteString("platform") ); 771 if (param == 0 || platform_fits( param->m_sValue )) { 772 param = params.find( ByteString("type") ); 773 if (param != 0) 774 { 775 String const & value = param->m_sValue; 776 if (value.EqualsIgnoreCaseAscii("native")) { 777 return new BackendImpl::ComponentPackageImpl( 778 this, url, name, m_xDynComponentTypeInfo, 779 OUSTR("com.sun.star.loader.SharedLibrary"), 780 bRemoved, identifier); 781 } 782 if (value.EqualsIgnoreCaseAscii("Java")) { 783 return new BackendImpl::ComponentPackageImpl( 784 this, url, name, m_xJavaComponentTypeInfo, 785 OUSTR("com.sun.star.loader.Java2"), 786 bRemoved, identifier); 787 } 788 if (value.EqualsIgnoreCaseAscii("Python")) { 789 return new BackendImpl::ComponentPackageImpl( 790 this, url, name, m_xPythonComponentTypeInfo, 791 OUSTR("com.sun.star.loader.Python"), 792 bRemoved, identifier); 793 } 794 } 795 } 796 } 797 else if (subType.EqualsIgnoreCaseAscii( 798 "vnd.sun.star.uno-components")) 799 { 800 INetContentTypeParameter const * param = params.find( 801 ByteString("platform") ); 802 if (param == 0 || platform_fits( param->m_sValue )) { 803 return new BackendImpl::ComponentsPackageImpl( 804 this, url, name, m_xComponentsTypeInfo, bRemoved, 805 identifier); 806 } 807 } 808 else if (subType.EqualsIgnoreCaseAscii( 809 "vnd.sun.star.uno-typelibrary")) 810 { 811 INetContentTypeParameter const * param = params.find( 812 ByteString("type") ); 813 if (param != 0) { 814 String const & value = param->m_sValue; 815 if (value.EqualsIgnoreCaseAscii("RDB")) 816 { 817 return new BackendImpl::TypelibraryPackageImpl( 818 this, url, name, m_xRDBTypelibTypeInfo, 819 false /* rdb */, bRemoved, identifier); 820 } 821 if (value.EqualsIgnoreCaseAscii("Java")) { 822 return new BackendImpl::TypelibraryPackageImpl( 823 this, url, name, m_xJavaTypelibTypeInfo, 824 true /* jar */, bRemoved, identifier); 825 } 826 } 827 } 828 } 829 } 830 throw lang::IllegalArgumentException( 831 StrUnsupportedMediaType::get() + mediaType, 832 static_cast<OWeakObject *>(this), 833 static_cast<sal_Int16>(-1) ); 834 } 835 836 //############################################################################## 837 838 //______________________________________________________________________________ 839 void BackendImpl::unorc_verify_init( 840 Reference<XCommandEnvironment> const & xCmdEnv ) 841 { 842 if (transientMode()) 843 return; 844 const ::osl::MutexGuard guard( getMutex() ); 845 if (! m_unorc_inited) 846 { 847 // common rc: 848 ::ucbhelper::Content ucb_content; 849 if (create_ucb_content( 850 &ucb_content, 851 makeURL( getCachePath(), OUSTR("unorc") ), 852 xCmdEnv, false /* no throw */ )) 853 { 854 OUString line; 855 if (readLine( &line, OUSTR("UNO_JAVA_CLASSPATH="), ucb_content, 856 RTL_TEXTENCODING_UTF8 )) 857 { 858 sal_Int32 index = sizeof ("UNO_JAVA_CLASSPATH=") - 1; 859 do { 860 OUString token( line.getToken( 0, ' ', index ).trim() ); 861 if (token.getLength() > 0) 862 { 863 if (create_ucb_content( 864 0, expandUnoRcTerm(token), xCmdEnv, 865 false /* no throw */ )) 866 { 867 //The jar file may not exist anymore if a shared or bundled 868 //extension was removed, but it can still be in the unorc 869 //After running XExtensionManager::synchronize, the unorc is 870 //cleaned up 871 m_jar_typelibs.push_back( token ); 872 } 873 } 874 } 875 while (index >= 0); 876 } 877 if (readLine( &line, OUSTR("UNO_TYPES="), ucb_content, 878 RTL_TEXTENCODING_UTF8 )) { 879 sal_Int32 index = sizeof ("UNO_TYPES=") - 1; 880 do { 881 OUString token( line.getToken( 0, ' ', index ).trim() ); 882 if (token.getLength() > 0) 883 { 884 if (token[ 0 ] == '?') 885 token = token.copy( 1 ); 886 if (create_ucb_content( 887 0, expandUnoRcTerm(token), xCmdEnv, 888 false /* no throw */ )) 889 { 890 //The RDB file may not exist anymore if a shared or bundled 891 //extension was removed, but it can still be in the unorc. 892 //After running XExtensionManager::synchronize, the unorc is 893 //cleaned up 894 m_rdb_typelibs.push_back( token ); 895 } 896 } 897 } 898 while (index >= 0); 899 } 900 if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content, 901 RTL_TEXTENCODING_UTF8 )) 902 { 903 // The UNO_SERVICES line always has the BNF form 904 // "UNO_SERVICES=" 905 // ("?$ORIGIN/" <common-rdb>)? -- first 906 // "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}"? -- second 907 // ("?" ("BUNDLED_EXTENSIONS" | -- third 908 // "UNO_SHARED_PACKAGES_CACHE" | "UNO_USER_PACKAGES_CACHE") 909 // ...)* 910 // so can unambiguously be split into its thre parts: 911 int state = 1; 912 for (sal_Int32 i = RTL_CONSTASCII_LENGTH("UNO_SERVICES="); 913 i >= 0;) 914 { 915 rtl::OUString token(line.getToken(0, ' ', i)); 916 if (token.getLength() != 0) 917 { 918 if (state == 1 && 919 token.matchAsciiL( 920 RTL_CONSTASCII_STRINGPARAM("?$ORIGIN/"))) 921 { 922 m_commonRDB_RO = token.copy( 923 RTL_CONSTASCII_LENGTH("?$ORIGIN/")); 924 state = 2; 925 } 926 else if (state <= 2 && 927 token.equalsAsciiL( 928 RTL_CONSTASCII_STRINGPARAM( 929 "${$ORIGIN/${_OS}_${_ARCH}rc:" 930 "UNO_SERVICES}"))) 931 { 932 state = 3; 933 } 934 else 935 { 936 if (token[0] == '?') 937 { 938 token = token.copy(1); 939 } 940 m_components.push_back(token); 941 state = 3; 942 } 943 } 944 } 945 } 946 947 // native rc: 948 if (create_ucb_content( 949 &ucb_content, 950 makeURL( getCachePath(), getPlatformString() + OUSTR("rc")), 951 xCmdEnv, false /* no throw */ )) { 952 if (readLine( &line, OUSTR("UNO_SERVICES="), ucb_content, 953 RTL_TEXTENCODING_UTF8 )) { 954 m_nativeRDB_RO = line.copy( 955 sizeof ("UNO_SERVICES=?$ORIGIN/") - 1 ); 956 } 957 } 958 } 959 m_unorc_modified = false; 960 m_unorc_inited = true; 961 } 962 } 963 964 //______________________________________________________________________________ 965 void BackendImpl::unorc_flush( Reference<XCommandEnvironment> const & xCmdEnv ) 966 { 967 if (transientMode()) 968 return; 969 if (!m_unorc_inited || !m_unorc_modified) 970 return; 971 972 ::rtl::OStringBuffer buf; 973 974 buf.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN=")); 975 OUString sOrigin = dp_misc::makeRcTerm(m_cachePath); 976 ::rtl::OString osOrigin = ::rtl::OUStringToOString(sOrigin, RTL_TEXTENCODING_UTF8); 977 buf.append(osOrigin); 978 buf.append(LF); 979 980 if (! m_jar_typelibs.empty()) 981 { 982 t_stringlist::const_iterator iPos( m_jar_typelibs.begin() ); 983 t_stringlist::const_iterator const iEnd( m_jar_typelibs.end() ); 984 buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_JAVA_CLASSPATH=") ); 985 while (iPos != iEnd) { 986 // encoded ASCII file-urls: 987 const ::rtl::OString item( 988 ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) ); 989 buf.append( item ); 990 ++iPos; 991 if (iPos != iEnd) 992 buf.append( ' ' ); 993 } 994 buf.append(LF); 995 } 996 if (! m_rdb_typelibs.empty()) 997 { 998 t_stringlist::const_iterator iPos( m_rdb_typelibs.begin() ); 999 t_stringlist::const_iterator const iEnd( m_rdb_typelibs.end() ); 1000 buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_TYPES=") ); 1001 while (iPos != iEnd) { 1002 buf.append( '?' ); 1003 // encoded ASCII file-urls: 1004 const ::rtl::OString item( 1005 ::rtl::OUStringToOString( *iPos, RTL_TEXTENCODING_ASCII_US ) ); 1006 buf.append( item ); 1007 ++iPos; 1008 if (iPos != iEnd) 1009 buf.append( ' ' ); 1010 } 1011 buf.append(LF); 1012 } 1013 1014 // If we duplicated the common or native rdb then we must use those urls 1015 //otherwise we use those of the original files. That is, m_commonRDB_RO and 1016 //m_nativeRDB_RO; 1017 OUString sCommonRDB(m_commonRDB.getLength() > 0 ? m_commonRDB : m_commonRDB_RO); 1018 OUString sNativeRDB(m_nativeRDB.getLength() > 0 ? m_nativeRDB : m_nativeRDB_RO); 1019 1020 if (sCommonRDB.getLength() > 0 || sNativeRDB.getLength() > 0 || 1021 !m_components.empty()) 1022 { 1023 buf.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=") ); 1024 bool space = false; 1025 if (sCommonRDB.getLength() > 0) 1026 { 1027 buf.append( RTL_CONSTASCII_STRINGPARAM("?$ORIGIN/") ); 1028 buf.append( ::rtl::OUStringToOString( 1029 sCommonRDB, RTL_TEXTENCODING_ASCII_US ) ); 1030 space = true; 1031 } 1032 if (sNativeRDB.getLength() > 0) 1033 { 1034 if (space) 1035 { 1036 buf.append(' '); 1037 } 1038 buf.append( RTL_CONSTASCII_STRINGPARAM( 1039 "${$ORIGIN/${_OS}_${_ARCH}rc:UNO_SERVICES}") ); 1040 space = true; 1041 1042 // write native rc: 1043 ::rtl::OStringBuffer buf2; 1044 buf2.append(RTL_CONSTASCII_STRINGPARAM("ORIGIN=")); 1045 buf2.append(osOrigin); 1046 buf2.append(LF); 1047 buf2.append( RTL_CONSTASCII_STRINGPARAM("UNO_SERVICES=?$ORIGIN/") ); 1048 buf2.append( ::rtl::OUStringToOString( 1049 sNativeRDB, RTL_TEXTENCODING_ASCII_US ) ); 1050 buf2.append(LF); 1051 1052 const Reference<io::XInputStream> xData( 1053 ::xmlscript::createInputStream( 1054 ::rtl::ByteSequence( 1055 reinterpret_cast<sal_Int8 const *>(buf2.getStr()), 1056 buf2.getLength() ) ) ); 1057 ::ucbhelper::Content ucb_content( 1058 makeURL( getCachePath(), getPlatformString() + OUSTR("rc") ), 1059 xCmdEnv ); 1060 ucb_content.writeStream( xData, true /* replace existing */ ); 1061 } 1062 for (t_stringlist::iterator i(m_components.begin()); 1063 i != m_components.end(); ++i) 1064 { 1065 if (space) 1066 { 1067 buf.append(' '); 1068 } 1069 buf.append('?'); 1070 buf.append(rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8)); 1071 space = true; 1072 } 1073 buf.append(LF); 1074 } 1075 1076 // write unorc: 1077 const Reference<io::XInputStream> xData( 1078 ::xmlscript::createInputStream( 1079 ::rtl::ByteSequence( 1080 reinterpret_cast<sal_Int8 const *>(buf.getStr()), 1081 buf.getLength() ) ) ); 1082 ::ucbhelper::Content ucb_content( 1083 makeURL( getCachePath(), OUSTR("unorc") ), xCmdEnv ); 1084 ucb_content.writeStream( xData, true /* replace existing */ ); 1085 1086 m_unorc_modified = false; 1087 } 1088 1089 //______________________________________________________________________________ 1090 bool BackendImpl::addToUnoRc( RcItem kind, OUString const & url_, 1091 Reference<XCommandEnvironment> const & xCmdEnv ) 1092 { 1093 const OUString rcterm( dp_misc::makeRcTerm(url_) ); 1094 const ::osl::MutexGuard guard( getMutex() ); 1095 unorc_verify_init( xCmdEnv ); 1096 t_stringlist & rSet = getRcItemList(kind); 1097 if (::std::find( rSet.begin(), rSet.end(), rcterm ) == rSet.end()) { 1098 rSet.push_front( rcterm ); // prepend to list, thus overriding 1099 // write immediately: 1100 m_unorc_modified = true; 1101 unorc_flush( xCmdEnv ); 1102 return true; 1103 } 1104 else 1105 return false; 1106 } 1107 1108 //______________________________________________________________________________ 1109 bool BackendImpl::removeFromUnoRc( 1110 RcItem kind, OUString const & url_, 1111 Reference<XCommandEnvironment> const & xCmdEnv ) 1112 { 1113 const OUString rcterm( dp_misc::makeRcTerm(url_) ); 1114 const ::osl::MutexGuard guard( getMutex() ); 1115 unorc_verify_init( xCmdEnv ); 1116 getRcItemList(kind).remove( rcterm ); 1117 // write immediately: 1118 m_unorc_modified = true; 1119 unorc_flush( xCmdEnv ); 1120 return true; 1121 } 1122 1123 //______________________________________________________________________________ 1124 bool BackendImpl::hasInUnoRc( 1125 RcItem kind, OUString const & url_ ) 1126 { 1127 const OUString rcterm( dp_misc::makeRcTerm(url_) ); 1128 const ::osl::MutexGuard guard( getMutex() ); 1129 t_stringlist const & rSet = getRcItemList(kind); 1130 return ::std::find( rSet.begin(), rSet.end(), rcterm ) != rSet.end(); 1131 } 1132 1133 css::uno::Reference< css::registry::XRegistryKey > BackendImpl::openRegistryKey( 1134 css::uno::Reference< css::registry::XRegistryKey > const & base, 1135 rtl::OUString const & path) 1136 { 1137 OSL_ASSERT(base.is()); 1138 css::uno::Reference< css::registry::XRegistryKey > key(base->openKey(path)); 1139 if (!key.is()) { 1140 throw css::deployment::DeploymentException( 1141 (rtl::OUString( 1142 RTL_CONSTASCII_USTRINGPARAM("missing registry entry ")) + 1143 path + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" under ")) + 1144 base->getKeyName()), 1145 static_cast< OWeakObject * >(this), Any()); 1146 } 1147 return key; 1148 } 1149 1150 void BackendImpl::extractComponentData( 1151 css::uno::Reference< css::uno::XComponentContext > const & context, 1152 css::uno::Reference< css::registry::XRegistryKey > const & registry, 1153 ComponentBackendDb::Data * data, 1154 std::vector< css::uno::Reference< css::uno::XInterface > > * factories, 1155 css::uno::Reference< css::loader::XImplementationLoader > const * 1156 componentLoader, 1157 rtl::OUString const * componentUrl) 1158 { 1159 OSL_ASSERT(context.is() && registry.is() && data != 0 && factories != 0); 1160 rtl::OUString registryName(registry->getKeyName()); 1161 sal_Int32 prefix = registryName.getLength(); 1162 if (!registryName.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM("/"))) { 1163 prefix += RTL_CONSTASCII_LENGTH("/"); 1164 } 1165 css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > > 1166 keys(registry->openKeys()); 1167 css::uno::Reference< css::lang::XMultiComponentFactory > smgr( 1168 context->getServiceManager(), css::uno::UNO_QUERY_THROW); 1169 for (sal_Int32 i = 0; i < keys.getLength(); ++i) { 1170 rtl::OUString name(keys[i]->getKeyName().copy(prefix)); 1171 data->implementationNames.push_back(name); 1172 css::uno::Reference< css::registry::XRegistryKey > singletons( 1173 keys[i]->openKey( 1174 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UNO/SINGLETONS")))); 1175 if (singletons.is()) { 1176 sal_Int32 prefix2 = keys[i]->getKeyName().getLength() + 1177 RTL_CONSTASCII_LENGTH("/UNO/SINGLETONS/"); 1178 css::uno::Sequence< 1179 css::uno::Reference< css::registry::XRegistryKey > > 1180 singletonKeys(singletons->openKeys()); 1181 for (sal_Int32 j = 0; j < singletonKeys.getLength(); ++j) { 1182 data->singletons.push_back( 1183 std::pair< rtl::OUString, rtl::OUString >( 1184 singletonKeys[j]->getKeyName().copy(prefix2), name)); 1185 } 1186 } 1187 css::uno::Reference< css::loader::XImplementationLoader > loader; 1188 if (componentLoader == 0) { 1189 rtl::OUString activator( 1190 openRegistryKey( 1191 keys[i], 1192 rtl::OUString( 1193 RTL_CONSTASCII_USTRINGPARAM("UNO/ACTIVATOR")))-> 1194 getAsciiValue()); 1195 loader.set( 1196 smgr->createInstanceWithContext(activator, context), 1197 css::uno::UNO_QUERY); 1198 if (!loader.is()) { 1199 throw css::deployment::DeploymentException( 1200 (rtl::OUString( 1201 RTL_CONSTASCII_USTRINGPARAM( 1202 "cannot instantiate loader ")) + 1203 activator), 1204 static_cast< OWeakObject * >(this), Any()); 1205 } 1206 } else { 1207 OSL_ASSERT(componentLoader->is()); 1208 loader = *componentLoader; 1209 } 1210 factories->push_back( 1211 loader->activate( 1212 name, rtl::OUString(), 1213 (componentUrl == 0 1214 ? (openRegistryKey( 1215 keys[i], 1216 rtl::OUString( 1217 RTL_CONSTASCII_USTRINGPARAM("UNO/LOCATION")))-> 1218 getAsciiValue()) 1219 : *componentUrl), 1220 keys[i])); 1221 } 1222 } 1223 1224 void BackendImpl::componentLiveInsertion( 1225 ComponentBackendDb::Data const & data, 1226 std::vector< css::uno::Reference< css::uno::XInterface > > const & 1227 factories) 1228 { 1229 css::uno::Reference< css::container::XSet > set( 1230 getComponentContext()->getServiceManager(), css::uno::UNO_QUERY_THROW); 1231 std::vector< css::uno::Reference< css::uno::XInterface > >::const_iterator 1232 factory(factories.begin()); 1233 for (t_stringlist::const_iterator i(data.implementationNames.begin()); 1234 i != data.implementationNames.end(); ++i) 1235 { 1236 try { 1237 set->insert(css::uno::Any(*factory++)); 1238 } catch (container::ElementExistException &) { 1239 OSL_TRACE( 1240 "implementation %s already registered", 1241 rtl::OUStringToOString(*i, RTL_TEXTENCODING_UTF8).getStr()); 1242 } 1243 } 1244 if (!data.singletons.empty()) { 1245 css::uno::Reference< css::container::XNameContainer > 1246 rootContext( 1247 getComponentContext()->getValueByName( 1248 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_root"))), 1249 css::uno::UNO_QUERY); 1250 if (rootContext.is()) { 1251 for (t_stringpairvec::const_iterator i(data.singletons.begin()); 1252 i != data.singletons.end(); ++i) 1253 { 1254 rtl::OUString name( 1255 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/")) + 1256 i->first); 1257 try { 1258 rootContext->removeByName( 1259 name + 1260 rtl::OUString( 1261 RTL_CONSTASCII_USTRINGPARAM("/arguments"))); 1262 } catch (container::NoSuchElementException &) {} 1263 try { 1264 rootContext->insertByName( 1265 (name + 1266 rtl::OUString( 1267 RTL_CONSTASCII_USTRINGPARAM("/service"))), 1268 css::uno::Any(i->second)); 1269 } catch (container::ElementExistException &) { 1270 rootContext->replaceByName( 1271 (name + 1272 rtl::OUString( 1273 RTL_CONSTASCII_USTRINGPARAM("/service"))), 1274 css::uno::Any(i->second)); 1275 } 1276 try { 1277 rootContext->insertByName(name, css::uno::Any()); 1278 } catch (container::ElementExistException &) { 1279 OSL_TRACE( 1280 "singleton %s already registered", 1281 rtl::OUStringToOString( 1282 i->first, RTL_TEXTENCODING_UTF8).getStr()); 1283 rootContext->replaceByName(name, css::uno::Any()); 1284 } 1285 } 1286 } 1287 } 1288 } 1289 1290 void BackendImpl::componentLiveRemoval(ComponentBackendDb::Data const & data) { 1291 css::uno::Reference< css::container::XSet > set( 1292 getComponentContext()->getServiceManager(), css::uno::UNO_QUERY_THROW); 1293 for (t_stringlist::const_iterator i(data.implementationNames.begin()); 1294 i != data.implementationNames.end(); ++i) 1295 { 1296 try { 1297 set->remove(css::uno::Any(*i)); 1298 } catch (css::container::NoSuchElementException &) { 1299 // ignore if factory has not been live deployed 1300 } 1301 } 1302 if (!data.singletons.empty()) { 1303 css::uno::Reference< css::container::XNameContainer > rootContext( 1304 getComponentContext()->getValueByName( 1305 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_root"))), 1306 css::uno::UNO_QUERY); 1307 if (rootContext.is()) { 1308 for (t_stringpairvec::const_iterator i(data.singletons.begin()); 1309 i != data.singletons.end(); ++i) 1310 { 1311 rtl::OUString name( 1312 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/singletons/")) + 1313 i->first); 1314 try { 1315 rootContext->removeByName( 1316 name + 1317 rtl::OUString( 1318 RTL_CONSTASCII_USTRINGPARAM("/arguments"))); 1319 rootContext->removeByName( 1320 name + 1321 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/service"))); 1322 rootContext->removeByName(name); 1323 } catch (container::NoSuchElementException &) {} 1324 } 1325 } 1326 } 1327 } 1328 1329 //______________________________________________________________________________ 1330 void BackendImpl::releaseObject( OUString const & id ) 1331 { 1332 const ::osl::MutexGuard guard( getMutex() ); 1333 m_backendObjects.erase( id ); 1334 } 1335 1336 //______________________________________________________________________________ 1337 Reference<XInterface> BackendImpl::getObject( OUString const & id ) 1338 { 1339 const ::osl::MutexGuard guard( getMutex() ); 1340 const t_string2object::const_iterator iFind( m_backendObjects.find( id ) ); 1341 if (iFind == m_backendObjects.end()) 1342 return Reference<XInterface>(); 1343 else 1344 return iFind->second; 1345 } 1346 1347 //______________________________________________________________________________ 1348 Reference<XInterface> BackendImpl::insertObject( 1349 OUString const & id, Reference<XInterface> const & xObject ) 1350 { 1351 const ::osl::MutexGuard guard( getMutex() ); 1352 const ::std::pair<t_string2object::iterator, bool> insertion( 1353 m_backendObjects.insert( t_string2object::value_type( 1354 id, xObject ) ) ); 1355 return insertion.first->second; 1356 } 1357 1358 //------------------------------------------------------------------------------ 1359 Reference<XComponentContext> raise_uno_process( 1360 Reference<XComponentContext> const & xContext, 1361 ::rtl::Reference<AbortChannel> const & abortChannel ) 1362 { 1363 OSL_ASSERT( xContext.is() ); 1364 1365 ::rtl::OUString url( 1366 Reference<util::XMacroExpander>( 1367 xContext->getValueByName( 1368 OUSTR("/singletons/com.sun.star.util.theMacroExpander") ), 1369 UNO_QUERY_THROW )-> 1370 expandMacros( OUSTR("$URE_BIN_DIR/uno") ) ); 1371 1372 ::rtl::OUStringBuffer buf; 1373 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno:pipe,name=") ); 1374 OUString pipeId( generateRandomPipeId() ); 1375 buf.append( pipeId ); 1376 buf.appendAscii( 1377 RTL_CONSTASCII_STRINGPARAM(";urp;uno.ComponentContext") ); 1378 const OUString connectStr( buf.makeStringAndClear() ); 1379 1380 // raise core UNO process to register/run a component, 1381 // javavm service uses unorc next to executable to retrieve deployed 1382 // jar typelibs 1383 1384 ::std::vector<OUString> args; 1385 #if OSL_DEBUG_LEVEL <= 1 1386 args.push_back( OUSTR("--quiet") ); 1387 #endif 1388 args.push_back( OUSTR("--singleaccept") ); 1389 args.push_back( OUSTR("-u") ); 1390 args.push_back( connectStr ); 1391 // don't inherit from unorc: 1392 args.push_back( OUSTR("-env:INIFILENAME=") ); 1393 1394 //now add the bootstrap variables which were supplied on the command line 1395 ::std::vector<OUString> bootvars = getCmdBootstrapVariables(); 1396 args.insert(args.end(), bootvars.begin(), bootvars.end()); 1397 1398 oslProcess hProcess = raiseProcess( 1399 url, comphelper::containerToSequence(args) ); 1400 try { 1401 return Reference<XComponentContext>( 1402 resolveUnoURL( connectStr, xContext, abortChannel.get() ), 1403 UNO_QUERY_THROW ); 1404 } 1405 catch (...) { 1406 // try to terminate process: 1407 if ( osl_terminateProcess( hProcess ) != osl_Process_E_None ) 1408 { 1409 OSL_ASSERT( false ); 1410 } 1411 throw; 1412 } 1413 } 1414 1415 //------------------------------------------------------------------------------ 1416 void BackendImpl::ComponentPackageImpl::getComponentInfo( 1417 ComponentBackendDb::Data * data, 1418 std::vector< css::uno::Reference< css::uno::XInterface > > * factories, 1419 Reference<XComponentContext> const & xContext ) 1420 { 1421 const Reference<loader::XImplementationLoader> xLoader( 1422 xContext->getServiceManager()->createInstanceWithContext( 1423 m_loader, xContext ), UNO_QUERY ); 1424 if (! xLoader.is()) 1425 { 1426 throw css::deployment::DeploymentException( 1427 (rtl::OUString( 1428 RTL_CONSTASCII_USTRINGPARAM("cannot instantiate loader ")) + 1429 m_loader), 1430 static_cast< OWeakObject * >(this), Any()); 1431 } 1432 1433 // HACK: highly dependent on stoc/source/servicemanager 1434 // and stoc/source/implreg implementation which rely on the same 1435 // services.rdb format! 1436 // .../UNO/LOCATION and .../UNO/ACTIVATOR appear not to be written by 1437 // writeRegistryInfo, however, but are knwon, fixed values here, so 1438 // can be passed into extractComponentData 1439 rtl::OUString url(getURL()); 1440 const Reference<registry::XSimpleRegistry> xMemReg( 1441 xContext->getServiceManager()->createInstanceWithContext( 1442 OUSTR("com.sun.star.registry.SimpleRegistry"), xContext ), 1443 UNO_QUERY_THROW ); 1444 xMemReg->open( OUString() /* in mem */, false, true ); 1445 xLoader->writeRegistryInfo( xMemReg->getRootKey(), OUString(), url ); 1446 getMyBackend()->extractComponentData( 1447 xContext, xMemReg->getRootKey(), data, factories, &xLoader, &url); 1448 } 1449 1450 // Package 1451 //______________________________________________________________________________ 1452 //We could use here BackendImpl::hasActiveEntry. However, this check is just as well. 1453 //And it also shows the problem if another extension has overwritten an implementation 1454 //entry, because it contains the same service implementation 1455 beans::Optional< beans::Ambiguous<sal_Bool> > 1456 BackendImpl::ComponentPackageImpl::isRegistered_( 1457 ::osl::ResettableMutexGuard &, 1458 ::rtl::Reference<AbortChannel> const & abortChannel, 1459 Reference<XCommandEnvironment> const & ) 1460 { 1461 if (m_registered == REG_UNINIT) 1462 { 1463 m_registered = REG_NOT_REGISTERED; 1464 bool bAmbiguousComponentName = false; 1465 const Reference<registry::XSimpleRegistry> xRDB( getRDB_RO() ); 1466 if (xRDB.is()) 1467 { 1468 // lookup rdb for location URL: 1469 const Reference<registry::XRegistryKey> xRootKey( 1470 xRDB->getRootKey() ); 1471 const Reference<registry::XRegistryKey> xImplKey( 1472 xRootKey->openKey( OUSTR("IMPLEMENTATIONS") ) ); 1473 Sequence<OUString> implNames; 1474 if (xImplKey.is() && xImplKey->isValid()) 1475 implNames = xImplKey->getKeyNames(); 1476 OUString const * pImplNames = implNames.getConstArray(); 1477 sal_Int32 pos = implNames.getLength(); 1478 for ( ; pos--; ) 1479 { 1480 checkAborted( abortChannel ); 1481 const OUString key( 1482 pImplNames[ pos ] + OUSTR("/UNO/LOCATION") ); 1483 const Reference<registry::XRegistryKey> xKey( 1484 xRootKey->openKey(key) ); 1485 if (xKey.is() && xKey->isValid()) 1486 { 1487 const OUString location( xKey->getAsciiValue() ); 1488 if (location.equalsIgnoreAsciiCase( getURL() )) 1489 { 1490 break; 1491 } 1492 else 1493 { 1494 //try to match only the file name 1495 OUString thisUrl(getURL()); 1496 OUString thisFileName(thisUrl.copy(thisUrl.lastIndexOf('/'))); 1497 1498 OUString locationFileName(location.copy(location.lastIndexOf('/'))); 1499 if (locationFileName.equalsIgnoreAsciiCase(thisFileName)) 1500 bAmbiguousComponentName = true; 1501 } 1502 } 1503 } 1504 if (pos >= 0) 1505 m_registered = REG_REGISTERED; 1506 else if (bAmbiguousComponentName) 1507 m_registered = REG_MAYBE_REGISTERED; 1508 } 1509 } 1510 1511 //Different extensions can use the same service implementations. Then the extensions 1512 //which was installed last will overwrite the one from the other extension. That is 1513 //the registry will contain the path (the location) of the library or jar of the 1514 //second extension. In this case isRegistered called for the lib of the first extension 1515 //would return "not registered". That would mean that during uninstallation 1516 //XPackage::registerPackage is not called, because it just was not registered. This is, 1517 //however, necessary for jar files. Registering and unregistering update 1518 //uno_packages/cache/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc 1519 //Therefore, we will return always "is ambiguous" if the path of this component cannot 1520 //be found in the registry and if there is another path and both have the same file name (but 1521 //the rest of the path is different). 1522 //If the caller cannot precisely determine that this package was registered, then it must 1523 //call registerPackage. 1524 sal_Bool bAmbiguous = m_registered == REG_VOID // REG_VOID == we are in the progress of unregistration 1525 || m_registered == REG_MAYBE_REGISTERED; 1526 return beans::Optional< beans::Ambiguous<sal_Bool> >( 1527 true /* IsPresent */, 1528 beans::Ambiguous<sal_Bool>( 1529 m_registered == REG_REGISTERED, bAmbiguous) ); 1530 } 1531 1532 //______________________________________________________________________________ 1533 void BackendImpl::ComponentPackageImpl::processPackage_( 1534 ::osl::ResettableMutexGuard &, 1535 bool doRegisterPackage, 1536 bool startup, 1537 ::rtl::Reference<AbortChannel> const & abortChannel, 1538 Reference<XCommandEnvironment> const & xCmdEnv ) 1539 { 1540 BackendImpl * that = getMyBackend(); 1541 rtl::OUString url(getURL()); 1542 if (doRegisterPackage) { 1543 ComponentBackendDb::Data data; 1544 css::uno::Reference< css::uno::XComponentContext > context; 1545 if (startup) { 1546 context = that->getComponentContext(); 1547 } else { 1548 context.set(that->getObject(url), css::uno::UNO_QUERY); 1549 if (!context.is()) { 1550 context.set( 1551 that->insertObject( 1552 url, 1553 raise_uno_process( 1554 that->getComponentContext(), abortChannel)), 1555 css::uno::UNO_QUERY_THROW); 1556 } 1557 } 1558 css::uno::Reference< css::registry::XImplementationRegistration>( 1559 context->getServiceManager()->createInstanceWithContext( 1560 rtl::OUString( 1561 RTL_CONSTASCII_USTRINGPARAM( 1562 "com.sun.star.registry.ImplementationRegistration")), 1563 context), 1564 css::uno::UNO_QUERY_THROW)->registerImplementation( 1565 m_loader, url, getRDB()); 1566 // Only write to unorc after successful registration; it may fail if 1567 // there is no suitable java 1568 if (m_loader.equalsAsciiL( 1569 RTL_CONSTASCII_STRINGPARAM("com.sun.star.loader.Java2")) && 1570 !jarManifestHeaderPresent(url, OUSTR("UNO-Type-Path"), xCmdEnv)) 1571 { 1572 that->addToUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv); 1573 data.javaTypeLibrary = true; 1574 } 1575 std::vector< css::uno::Reference< css::uno::XInterface > > factories; 1576 getComponentInfo(&data, &factories, context); 1577 if (!startup) { 1578 that->componentLiveInsertion(data, factories); 1579 } 1580 m_registered = REG_REGISTERED; 1581 that->addDataToDb(url, data); 1582 } else { // revoke 1583 m_registered = REG_VOID; 1584 ComponentBackendDb::Data data(that->readDataFromDb(url)); 1585 css::uno::Reference< css::uno::XComponentContext > context( 1586 that->getObject(url), css::uno::UNO_QUERY); 1587 bool remoteContext = context.is(); 1588 if (!remoteContext) { 1589 context = that->getComponentContext(); 1590 } 1591 if (!startup) { 1592 that->componentLiveRemoval(data); 1593 } 1594 css::uno::Reference< css::registry::XImplementationRegistration >( 1595 context->getServiceManager()->createInstanceWithContext( 1596 rtl::OUString( 1597 RTL_CONSTASCII_USTRINGPARAM( 1598 "com.sun.star.registry.ImplementationRegistration")), 1599 context), 1600 css::uno::UNO_QUERY_THROW)->revokeImplementation(url, getRDB()); 1601 if (data.javaTypeLibrary) { 1602 that->removeFromUnoRc(RCITEM_JAR_TYPELIB, url, xCmdEnv); 1603 } 1604 if (remoteContext) { 1605 that->releaseObject(url); 1606 } 1607 m_registered = REG_NOT_REGISTERED; 1608 getMyBackend()->revokeEntryFromDb(url); 1609 } 1610 } 1611 1612 //############################################################################## 1613 BackendImpl::TypelibraryPackageImpl::TypelibraryPackageImpl( 1614 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 1615 OUString const & url, OUString const & name, 1616 Reference<deployment::XPackageTypeInfo> const & xPackageType, 1617 bool jarFile, bool bRemoved, OUString const & identifier) 1618 : Package( myBackend, url, name, name /* display-name */, 1619 xPackageType, bRemoved, identifier), 1620 m_jarFile( jarFile ) 1621 { 1622 } 1623 1624 // Package 1625 BackendImpl * BackendImpl::TypelibraryPackageImpl::getMyBackend() const 1626 { 1627 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); 1628 if (NULL == pBackend) 1629 { 1630 //May throw a DisposedException 1631 check(); 1632 //We should never get here... 1633 throw RuntimeException( 1634 OUSTR("Failed to get the BackendImpl"), 1635 static_cast<OWeakObject*>(const_cast<TypelibraryPackageImpl *>(this))); 1636 } 1637 return pBackend; 1638 } 1639 //______________________________________________________________________________ 1640 beans::Optional< beans::Ambiguous<sal_Bool> > 1641 BackendImpl::TypelibraryPackageImpl::isRegistered_( 1642 ::osl::ResettableMutexGuard &, 1643 ::rtl::Reference<AbortChannel> const &, 1644 Reference<XCommandEnvironment> const & ) 1645 { 1646 BackendImpl * that = getMyBackend(); 1647 return beans::Optional< beans::Ambiguous<sal_Bool> >( 1648 true /* IsPresent */, 1649 beans::Ambiguous<sal_Bool>( 1650 that->hasInUnoRc( 1651 m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, getURL() ), 1652 false /* IsAmbiguous */ ) ); 1653 } 1654 1655 //______________________________________________________________________________ 1656 void BackendImpl::TypelibraryPackageImpl::processPackage_( 1657 ::osl::ResettableMutexGuard &, 1658 bool doRegisterPackage, 1659 bool /*startup*/, 1660 ::rtl::Reference<AbortChannel> const &, 1661 Reference<XCommandEnvironment> const & xCmdEnv ) 1662 { 1663 BackendImpl * that = getMyBackend(); 1664 const OUString url( getURL() ); 1665 1666 if (doRegisterPackage) 1667 { 1668 // live insertion: 1669 if (m_jarFile) { 1670 // xxx todo add to classpath at runtime: ??? 1671 //SB: It is probably not worth it to add the live inserted type 1672 // library JAR to the UnoClassLoader in the soffice process. Any 1673 // live inserted component JAR that might reference this type 1674 // library JAR runs in its own uno process, so there is probably no 1675 // Java code in the soffice process that would see any UNO types 1676 // introduced by this type library JAR. 1677 } 1678 else // RDB: 1679 { 1680 Reference<XComponentContext> const & xContext = 1681 that->getComponentContext(); 1682 if (! m_xTDprov.is()) 1683 { 1684 m_xTDprov.set( that->getObject( url ), UNO_QUERY ); 1685 if (! m_xTDprov.is()) 1686 { 1687 const Reference<registry::XSimpleRegistry> xReg( 1688 xContext->getServiceManager() 1689 ->createInstanceWithContext( 1690 OUSTR("com.sun.star.registry.SimpleRegistry"), 1691 xContext ), UNO_QUERY_THROW ); 1692 xReg->open( expandUnoRcUrl(url), 1693 true /* read-only */, false /* ! create */ ); 1694 const Any arg(xReg); 1695 Reference<container::XHierarchicalNameAccess> xTDprov( 1696 xContext->getServiceManager() 1697 ->createInstanceWithArgumentsAndContext( 1698 OUSTR("com.sun.star.comp.stoc." 1699 "RegistryTypeDescriptionProvider"), 1700 Sequence<Any>( &arg, 1 ), xContext ), UNO_QUERY ); 1701 OSL_ASSERT( xTDprov.is() ); 1702 if (xTDprov.is()) 1703 m_xTDprov.set( that->insertObject( url, xTDprov ), 1704 UNO_QUERY_THROW ); 1705 } 1706 } 1707 if (m_xTDprov.is()) { 1708 Reference<container::XSet> xSet( 1709 xContext->getValueByName( 1710 OUSTR("/singletons/com.sun.star." 1711 "reflection.theTypeDescriptionManager") ), 1712 UNO_QUERY_THROW ); 1713 xSet->insert( Any(m_xTDprov) ); 1714 } 1715 } 1716 1717 that->addToUnoRc( m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, 1718 url, xCmdEnv ); 1719 } 1720 else // revokePackage() 1721 { 1722 that->removeFromUnoRc( 1723 m_jarFile ? RCITEM_JAR_TYPELIB : RCITEM_RDB_TYPELIB, url, xCmdEnv ); 1724 1725 // revoking types at runtime, possible, sensible? 1726 if (!m_xTDprov.is()) 1727 m_xTDprov.set( that->getObject( url ), UNO_QUERY ); 1728 if (m_xTDprov.is()) { 1729 // remove live: 1730 const Reference<container::XSet> xSet( 1731 that->getComponentContext()->getValueByName( 1732 OUSTR("/singletons/com.sun.star." 1733 "reflection.theTypeDescriptionManager") ), 1734 UNO_QUERY_THROW ); 1735 xSet->remove( Any(m_xTDprov) ); 1736 1737 that->releaseObject( url ); 1738 m_xTDprov.clear(); 1739 } 1740 } 1741 } 1742 1743 BackendImpl * BackendImpl::ComponentsPackageImpl::getMyBackend() const 1744 { 1745 BackendImpl * pBackend = static_cast<BackendImpl *>(m_myBackend.get()); 1746 if (NULL == pBackend) 1747 { 1748 //Throws a DisposedException 1749 check(); 1750 //We should never get here... 1751 throw RuntimeException( 1752 OUSTR("Failed to get the BackendImpl"), 1753 static_cast<OWeakObject*>(const_cast<ComponentsPackageImpl *>(this))); 1754 } 1755 return pBackend; 1756 } 1757 1758 beans::Optional< beans::Ambiguous<sal_Bool> > 1759 BackendImpl::ComponentsPackageImpl::isRegistered_( 1760 ::osl::ResettableMutexGuard &, 1761 ::rtl::Reference<AbortChannel> const &, 1762 Reference<XCommandEnvironment> const & ) 1763 { 1764 return beans::Optional< beans::Ambiguous<sal_Bool> >( 1765 true, 1766 beans::Ambiguous<sal_Bool>( 1767 getMyBackend()->hasInUnoRc(RCITEM_COMPONENTS, getURL()), false)); 1768 } 1769 1770 void BackendImpl::ComponentsPackageImpl::processPackage_( 1771 ::osl::ResettableMutexGuard &, 1772 bool doRegisterPackage, 1773 bool startup, 1774 ::rtl::Reference<AbortChannel> const & abortChannel, 1775 Reference<XCommandEnvironment> const & xCmdEnv ) 1776 { 1777 BackendImpl * that = getMyBackend(); 1778 rtl::OUString url(getURL()); 1779 if (doRegisterPackage) { 1780 ComponentBackendDb::Data data; 1781 data.javaTypeLibrary = false; 1782 css::uno::Reference< css::uno::XComponentContext > context; 1783 if (startup) { 1784 context = that->getComponentContext(); 1785 } else { 1786 context.set(that->getObject(url), css::uno::UNO_QUERY); 1787 if (!context.is()) { 1788 context.set( 1789 that->insertObject( 1790 url, 1791 raise_uno_process( 1792 that->getComponentContext(), abortChannel)), 1793 css::uno::UNO_QUERY_THROW); 1794 } 1795 } 1796 1797 std::vector< css::uno::Reference< css::uno::XInterface > > factories; 1798 1799 css::uno::Reference< css::registry::XSimpleRegistry > registry( 1800 css::uno::Reference< css::lang::XMultiComponentFactory >( 1801 that->getComponentContext()->getServiceManager(), 1802 css::uno::UNO_SET_THROW)->createInstanceWithContext( 1803 rtl::OUString( 1804 RTL_CONSTASCII_USTRINGPARAM( 1805 "com.sun.star.registry.SimpleRegistry")), 1806 that->getComponentContext()), 1807 css::uno::UNO_QUERY_THROW); 1808 registry->open(expandUnoRcUrl(url), true, false); 1809 getMyBackend()->extractComponentData( 1810 context, 1811 that->openRegistryKey( 1812 registry->getRootKey(), 1813 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS"))), 1814 &data, &factories, 0, 0); 1815 registry->close(); 1816 if (!startup) { 1817 that->componentLiveInsertion(data, factories); 1818 } 1819 that->addDataToDb(url, data); 1820 that->addToUnoRc(RCITEM_COMPONENTS, url, xCmdEnv); 1821 } else { // revoke 1822 that->removeFromUnoRc(RCITEM_COMPONENTS, url, xCmdEnv); 1823 if (!startup) { 1824 that->componentLiveRemoval(that->readDataFromDb(url)); 1825 } 1826 that->releaseObject(url); 1827 that->revokeEntryFromDb(url); 1828 } 1829 } 1830 1831 BackendImpl::ComponentsPackageImpl::ComponentsPackageImpl( 1832 ::rtl::Reference<PackageRegistryBackend> const & myBackend, 1833 OUString const & url, OUString const & name, 1834 Reference<deployment::XPackageTypeInfo> const & xPackageType, 1835 bool bRemoved, OUString const & identifier) 1836 : Package( myBackend, url, name, name /* display-name */, 1837 xPackageType, bRemoved, identifier) 1838 {} 1839 1840 } // anon namespace 1841 1842 namespace sdecl = comphelper::service_decl; 1843 sdecl::class_<BackendImpl, sdecl::with_args<true> > serviceBI; 1844 extern sdecl::ServiceDecl const serviceDecl( 1845 serviceBI, 1846 IMPLEMENTATION_NAME, 1847 BACKEND_SERVICE_NAME ); 1848 1849 } // namespace component 1850 } // namespace backend 1851 } // namespace dp_registry 1852 1853 1854