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