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