1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 21 #include <comphelper/DisableInteractionHelper.hxx> 22 #include <comphelper/documentinfo.hxx> 23 24 #include <cppuhelper/implementationentry.hxx> 25 #include <cppuhelper/exc_hlp.hxx> 26 #include <cppuhelper/factory.hxx> 27 #include <cppuhelper/supportsservice.hxx> 28 #include <tools/diagnose_ex.h> 29 30 #include <com/sun/star/frame/XModel.hpp> 31 #include <com/sun/star/lang/EventObject.hpp> 32 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 33 #include <com/sun/star/document/XScriptInvocationContext.hpp> 34 #include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp> 35 #include <com/sun/star/uri/XUriReference.hpp> 36 #include <com/sun/star/uri/UriReferenceFactory.hpp> 37 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp> 38 39 #include <com/sun/star/deployment/XPackage.hpp> 40 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp> 41 #include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp> 42 #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp> 43 44 #include <util/MiscUtils.hxx> 45 #include <sal/log.hxx> 46 47 #include "ActiveMSPList.hxx" 48 #include "MasterScriptProvider.hxx" 49 #include "URIHelper.hxx" 50 51 using namespace ::com::sun::star; 52 using namespace ::com::sun::star::uno; 53 using namespace ::com::sun::star::script; 54 using namespace ::com::sun::star::document; 55 using namespace ::sf_misc; 56 57 namespace func_provider 58 { 59 60 static bool endsWith( const OUString& target, const OUString& item ) 61 { 62 sal_Int32 index = target.indexOf( item ); 63 return index != -1 && 64 index == ( target.getLength() - item.getLength() ); 65 } 66 67 /* should be available in some central location. */ 68 69 // XScriptProvider implementation 70 71 72 MasterScriptProvider::MasterScriptProvider( const Reference< XComponentContext > & xContext ): 73 m_xContext( xContext ), m_bIsValid( false ), m_bInitialised( false ), 74 m_bIsPkgMSP( false ) 75 { 76 ENSURE_OR_THROW( m_xContext.is(), "MasterScriptProvider::MasterScriptProvider: No context available\n" ); 77 m_xMgr = m_xContext->getServiceManager(); 78 ENSURE_OR_THROW( m_xMgr.is(), "MasterScriptProvider::MasterScriptProvider: No service manager available\n" ); 79 m_bIsValid = true; 80 } 81 82 83 MasterScriptProvider::~MasterScriptProvider() 84 { 85 } 86 87 88 void SAL_CALL MasterScriptProvider::initialize( const Sequence < Any >& args ) 89 { 90 if ( m_bInitialised ) 91 return; 92 93 m_bIsValid = false; 94 95 sal_Int32 len = args.getLength(); 96 if ( len > 1 ) 97 { 98 throw RuntimeException( 99 "MasterScriptProvider::initialize: invalid number of arguments" ); 100 } 101 102 Sequence< Any > invokeArgs( len ); 103 104 if ( len != 0 ) 105 { 106 // check if first parameter is a string 107 // if it is, this implies that this is a MSP created 108 // with a user or share ctx ( used for browse functionality ) 109 110 if ( args[ 0 ] >>= m_sCtxString ) 111 { 112 invokeArgs[ 0 ] = args[ 0 ]; 113 if ( m_sCtxString.startsWith( "vnd.sun.star.tdoc" ) ) 114 { 115 m_xModel = MiscUtils::tDocUrlToModel( m_sCtxString ); 116 } 117 } 118 else if ( args[ 0 ] >>= m_xInvocationContext ) 119 { 120 m_xModel.set( m_xInvocationContext->getScriptContainer(), UNO_QUERY_THROW ); 121 } 122 else 123 { 124 args[ 0 ] >>= m_xModel; 125 } 126 127 if ( m_xModel.is() ) 128 { 129 // from the arguments, we were able to deduce a model. That alone doesn't 130 // suffice, we also need an XEmbeddedScripts which actually indicates support 131 // for embedding scripts 132 Reference< XEmbeddedScripts > xScripts( m_xModel, UNO_QUERY ); 133 if ( !xScripts.is() ) 134 { 135 throw lang::IllegalArgumentException( 136 "The given document does not support embedding scripts into it, and cannot be associated with such a document.", 137 *this, 138 1 139 ); 140 } 141 142 try 143 { 144 m_sCtxString = MiscUtils::xModelToTdocUrl( m_xModel, m_xContext ); 145 } 146 catch ( const Exception& ) 147 { 148 Any aError( ::cppu::getCaughtException() ); 149 150 OUStringBuffer buf; 151 buf.append( "MasterScriptProvider::initialize: caught " ); 152 buf.append( aError.getValueTypeName() ); 153 buf.append( ":" ); 154 155 Exception aException; 156 aError >>= aException; 157 buf.append ( aException.Message ); 158 throw lang::WrappedTargetException( buf.makeStringAndClear(), *this, aError ); 159 } 160 161 if ( m_xInvocationContext.is() && m_xInvocationContext != m_xModel ) 162 invokeArgs[ 0 ] <<= m_xInvocationContext; 163 else 164 invokeArgs[ 0 ] <<= m_sCtxString; 165 } 166 167 OUString pkgSpec = "uno_packages"; 168 sal_Int32 indexOfPkgSpec = m_sCtxString.lastIndexOf( pkgSpec ); 169 170 // if contex string ends with "uno_packages" 171 if ( indexOfPkgSpec > -1 && m_sCtxString.match( pkgSpec, indexOfPkgSpec ) ) 172 { 173 m_bIsPkgMSP = true; 174 } 175 else 176 { 177 m_bIsPkgMSP = false; 178 } 179 } 180 else // no args 181 { 182 // use either scripting context or maybe zero args? 183 invokeArgs = Sequence< Any >( 0 ); // no arguments 184 } 185 m_sAargs = invokeArgs; 186 // don't create pkg mgr MSP for documents, not supported 187 if ( !m_bIsPkgMSP && !m_xModel.is() ) 188 { 189 createPkgProvider(); 190 } 191 192 m_bInitialised = true; 193 m_bIsValid = true; 194 } 195 196 197 void MasterScriptProvider::createPkgProvider() 198 { 199 try 200 { 201 Any location; 202 location <<= m_sCtxString + ":uno_packages"; 203 204 Reference< provider::XScriptProviderFactory > xFac = 205 provider::theMasterScriptProviderFactory::get( m_xContext ); 206 207 m_xMSPPkg.set( 208 xFac->createScriptProvider( location ), UNO_QUERY_THROW ); 209 210 } 211 catch ( const Exception& e ) 212 { 213 SAL_WARN("scripting.provider", "Exception creating MasterScriptProvider for uno_packages in context " 214 << m_sCtxString << ": " << e ); 215 } 216 } 217 218 219 Reference< provider::XScript > 220 MasterScriptProvider::getScript( const OUString& scriptURI ) 221 { 222 if ( !m_bIsValid ) 223 { 224 throw provider::ScriptFrameworkErrorException( 225 "MasterScriptProvider not initialised", Reference< XInterface >(), 226 scriptURI, "", 227 provider::ScriptFrameworkErrorType::UNKNOWN ); 228 } 229 230 // need to get the language from the string 231 232 Reference< uri::XUriReferenceFactory > xFac ( uri::UriReferenceFactory::create( m_xContext ) ); 233 234 Reference< uri::XUriReference > uriRef( 235 xFac->parse( scriptURI ), UNO_QUERY ); 236 237 Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY ); 238 239 if ( !uriRef.is() || !sfUri.is() ) 240 { 241 throw provider::ScriptFrameworkErrorException( 242 "Incorrect format for Script URI: " + scriptURI, 243 Reference< XInterface >(), 244 scriptURI, "", 245 provider::ScriptFrameworkErrorType::UNKNOWN ); 246 } 247 248 OUString langKey("language"); 249 OUString locKey("location"); 250 251 if ( !sfUri->hasParameter( langKey ) || 252 !sfUri->hasParameter( locKey ) || 253 ( sfUri->getName().isEmpty() ) ) 254 { 255 throw provider::ScriptFrameworkErrorException( 256 "Incorrect format for Script URI: " + scriptURI, 257 Reference< XInterface >(), 258 scriptURI, "", 259 provider::ScriptFrameworkErrorType::UNKNOWN ); 260 } 261 262 OUString language = sfUri->getParameter( langKey ); 263 OUString location = sfUri->getParameter( locKey ); 264 265 // if script us located in uno pkg 266 sal_Int32 index = -1; 267 OUString pkgTag(":uno_packages"); 268 // for languages other than basic, scripts located in uno packages 269 // are merged into the user/share location context. 270 // For other languages the location attribute in script url has the form 271 // location = [user|share]:uno_packages or location :uno_packages/xxxx.uno.pkg 272 // we need to extract the value of location part from the 273 // location attribute of the script, if the script is located in an 274 // uno package then that is the location part up to and including 275 // ":uno_packages", if the script is not in an uno package then the 276 // normal value is used e.g. user or share. 277 // The value extracted will be used to determine if the script is 278 // located in the same location context as this MSP. 279 // For Basic, the language script provider can handle the execution of a 280 // script in any location context 281 if ( ( index = location.indexOf( pkgTag ) ) > -1 ) 282 { 283 location = location.copy( 0, index + pkgTag.getLength() ); 284 } 285 286 Reference< provider::XScript > xScript; 287 288 // If the script location is in the same location context as this 289 // MSP then delete to the language provider controlled by this MSP 290 // ** Special case is BASIC, all calls to getScript will be handled 291 // by the language script provider in the current location context 292 // even if its different 293 if ( ( location == "document" 294 && m_xModel.is() 295 ) 296 || ( endsWith( m_sCtxString, location ) ) 297 || ( language == "Basic" ) 298 ) 299 { 300 Reference< provider::XScriptProvider > xScriptProvider; 301 OUStringBuffer buf( 80 ); 302 buf.append( "com.sun.star.script.provider.ScriptProviderFor"); 303 buf.append( language ); 304 OUString serviceName = buf.makeStringAndClear(); 305 if ( !providerCache() ) 306 { 307 throw provider::ScriptFrameworkErrorException( 308 "No LanguageProviders detected", 309 Reference< XInterface >(), 310 sfUri->getName(), language, 311 provider::ScriptFrameworkErrorType::NOTSUPPORTED ); 312 } 313 314 try 315 { 316 xScriptProvider.set( 317 providerCache()->getProvider( serviceName ), 318 UNO_QUERY_THROW ); 319 } 320 catch( const Exception& e ) 321 { 322 throw provider::ScriptFrameworkErrorException( 323 e.Message, Reference< XInterface >(), 324 sfUri->getName(), language, 325 provider::ScriptFrameworkErrorType::NOTSUPPORTED ); 326 } 327 328 xScript=xScriptProvider->getScript( scriptURI ); 329 } 330 else 331 { 332 Reference< provider::XScriptProviderFactory > xFac_ = 333 provider::theMasterScriptProviderFactory::get( m_xContext ); 334 335 Reference< provider::XScriptProvider > xSP( 336 xFac_->createScriptProvider( makeAny( location ) ), UNO_QUERY_THROW ); 337 xScript = xSP->getScript( scriptURI ); 338 } 339 340 return xScript; 341 } 342 343 344 ProviderCache* 345 MasterScriptProvider::providerCache() 346 { 347 if ( !m_pPCache ) 348 { 349 ::osl::MutexGuard aGuard( m_mutex ); 350 if ( !m_pPCache ) 351 { 352 OUString serviceName1 = "com.sun.star.script.provider.ScriptProviderForBasic"; 353 Sequence<OUString> blacklist { serviceName1 }; 354 355 if ( !m_bIsPkgMSP ) 356 { 357 m_pPCache.reset( new ProviderCache( m_xContext, m_sAargs ) ); 358 } 359 else 360 { 361 m_pPCache.reset( new ProviderCache( m_xContext, m_sAargs, blacklist ) ); 362 } 363 } 364 } 365 return m_pPCache.get(); 366 } 367 368 369 OUString SAL_CALL 370 MasterScriptProvider::getName() 371 { 372 if ( !m_bIsPkgMSP ) 373 { 374 OUString sCtx = getContextString(); 375 if ( sCtx.startsWith( "vnd.sun.star.tdoc" ) ) 376 { 377 Reference< frame::XModel > xModel = m_xModel; 378 if ( !xModel.is() ) 379 { 380 xModel = MiscUtils::tDocUrlToModel( sCtx ); 381 } 382 383 m_sNodeName = ::comphelper::DocumentInfo::getDocumentTitle( xModel ); 384 } 385 else 386 { 387 m_sNodeName = parseLocationName( getContextString() ); 388 } 389 } 390 else 391 { 392 m_sNodeName = "uno_packages"; 393 } 394 return m_sNodeName; 395 } 396 397 398 Sequence< Reference< browse::XBrowseNode > > SAL_CALL 399 MasterScriptProvider::getChildNodes() 400 { 401 Sequence< Reference< provider::XScriptProvider > > providers = providerCache()->getAllProviders(); 402 403 sal_Int32 size = providers.getLength(); 404 bool hasPkgs = m_xMSPPkg.is(); 405 if ( hasPkgs ) 406 { 407 size++; 408 } 409 Sequence< Reference< browse::XBrowseNode > > children( size ); 410 sal_Int32 provIndex = 0; 411 for ( ; provIndex < providers.getLength(); provIndex++ ) 412 { 413 children[ provIndex ].set( providers[ provIndex ], UNO_QUERY ); 414 } 415 416 if ( hasPkgs ) 417 { 418 children[ provIndex ].set( m_xMSPPkg, UNO_QUERY ); 419 420 } 421 422 return children; 423 } 424 425 426 sal_Bool SAL_CALL 427 MasterScriptProvider::hasChildNodes() 428 { 429 return true; 430 } 431 432 433 sal_Int16 SAL_CALL 434 MasterScriptProvider::getType() 435 { 436 return browse::BrowseNodeTypes::CONTAINER; 437 } 438 439 440 OUString 441 MasterScriptProvider::parseLocationName( const OUString& location ) 442 { 443 // strip out the last leaf of location name 444 // e.g. file://dir1/dir2/Blah.sxw - > Blah.sxw 445 OUString temp = location; 446 INetURLObject aURLObj( temp ); 447 if ( !aURLObj.HasError() ) 448 temp = aURLObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset ); 449 return temp; 450 } 451 452 namespace 453 { 454 template <typename Proc> bool FindProviderAndApply(ProviderCache& rCache, Proc p) 455 { 456 auto pass = [&rCache, &p]() -> bool 457 { 458 bool bResult = false; 459 for (auto& rProv : rCache.getAllProviders()) 460 { 461 Reference<container::XNameContainer> xCont(rProv, UNO_QUERY); 462 if (!xCont.is()) 463 { 464 continue; 465 } 466 try 467 { 468 bResult = p(xCont); 469 break; 470 } 471 catch (Exception& e) 472 { 473 SAL_INFO("scripting.provider", "ignoring " << e); 474 } 475 } 476 return bResult; 477 }; 478 bool bSuccess = false; 479 // 1. Try to perform the operation without trying to enable JVM (if disabled) 480 // This allows us to avoid useless user interaction in case when other provider 481 // (not JVM) actually handles the operation. 482 { 483 css::uno::ContextLayer layer( 484 new comphelper::NoEnableJavaInteractionContext(css::uno::getCurrentContext())); 485 bSuccess = pass(); 486 } 487 // 2. Now retry asking to enable JVM in case we didn't succeed first time 488 if (!bSuccess) 489 { 490 bSuccess = pass(); 491 } 492 return bSuccess; 493 } 494 } // namespace 495 496 // Register Package 497 void SAL_CALL 498 MasterScriptProvider::insertByName( const OUString& aName, const Any& aElement ) 499 { 500 if ( !m_bIsPkgMSP ) 501 { 502 if ( !m_xMSPPkg.is() ) 503 { 504 throw RuntimeException( "PackageMasterScriptProvider is unitialised" ); 505 } 506 507 Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY_THROW ); 508 xCont->insertByName( aName, aElement ); 509 } 510 else 511 { 512 Reference< deployment::XPackage > xPkg( aElement, UNO_QUERY ); 513 if ( !xPkg.is() ) 514 { 515 throw lang::IllegalArgumentException( "Couldn't convert to XPackage", 516 Reference < XInterface > (), 2 ); 517 } 518 if ( aName.isEmpty() ) 519 { 520 throw lang::IllegalArgumentException( "Name not set!!", 521 Reference < XInterface > (), 1 ); 522 } 523 // TODO for library package parse the language, for the moment will try 524 // to get each provider to process the new Package, the first one the succeeds 525 // will terminate processing 526 const bool bSuccess = FindProviderAndApply( 527 *providerCache(), [&aName, &aElement](Reference<container::XNameContainer>& xCont) { 528 xCont->insertByName(aName, aElement); 529 return true; 530 }); 531 if (!bSuccess) 532 { 533 // No script providers could process the package 534 throw lang::IllegalArgumentException( "Failed to register package for " + aName, 535 Reference < XInterface > (), 2 ); 536 } 537 } 538 } 539 540 541 // Revoke Package 542 void SAL_CALL 543 MasterScriptProvider::removeByName( const OUString& Name ) 544 { 545 if ( !m_bIsPkgMSP ) 546 { 547 if ( !m_xMSPPkg.is() ) 548 { 549 throw RuntimeException( "PackageMasterScriptProvider is unitialised" ); 550 } 551 552 Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY_THROW ); 553 xCont->removeByName( Name ); 554 } 555 else 556 { 557 if ( Name.isEmpty() ) 558 { 559 throw lang::IllegalArgumentException( "Name not set!!", 560 Reference < XInterface > (), 1 ); 561 } 562 // TODO for Script library package url parse the language, 563 // for the moment will just try to get each provider to process remove/revoke 564 // request, the first one the succeeds will terminate processing 565 const bool bSuccess = FindProviderAndApply( 566 *providerCache(), [&Name](Reference<container::XNameContainer>& xCont) { 567 xCont->removeByName(Name); 568 return true; 569 }); 570 if (!bSuccess) 571 { 572 // No script providers could process the package 573 throw lang::IllegalArgumentException( "Failed to revoke package for " + Name, 574 Reference < XInterface > (), 1 ); 575 } 576 577 } 578 } 579 580 581 void SAL_CALL 582 MasterScriptProvider::replaceByName( const OUString& /*aName*/, const Any& /*aElement*/ ) 583 { 584 // TODO needs implementing 585 throw RuntimeException( "replaceByName not implemented!!!!" ); 586 } 587 588 Any SAL_CALL 589 MasterScriptProvider::getByName( const OUString& /*aName*/ ) 590 { 591 // TODO needs to be implemented 592 throw RuntimeException( "getByName not implemented!!!!" ); 593 } 594 595 sal_Bool SAL_CALL 596 MasterScriptProvider::hasByName( const OUString& aName ) 597 { 598 bool result = false; 599 if ( !m_bIsPkgMSP ) 600 { 601 if ( m_xMSPPkg.is() ) 602 { 603 Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY_THROW ); 604 result = xCont->hasByName( aName ); 605 } 606 // If this is a document provider then we shouldn't 607 // have a PackageProvider 608 else if (!m_xModel.is()) 609 { 610 throw RuntimeException( "PackageMasterScriptProvider is unitialised" ); 611 } 612 613 } 614 else 615 { 616 if ( aName.isEmpty() ) 617 { 618 throw lang::IllegalArgumentException( "Name not set!!", 619 Reference < XInterface > (), 1 ); 620 } 621 // TODO for Script library package url parse the language, 622 // for the moment will just try to get each provider to see if the 623 // package exists in any provider, first one that succeed will 624 // terminate the loop 625 result = FindProviderAndApply( 626 *providerCache(), [&aName](Reference<container::XNameContainer>& xCont) { 627 return xCont->hasByName(aName); 628 }); 629 } 630 return result; 631 } 632 633 634 Sequence< OUString > SAL_CALL 635 MasterScriptProvider::getElementNames( ) 636 { 637 // TODO needs implementing 638 throw RuntimeException( "getElementNames not implemented!!!!" ); 639 } 640 641 Type SAL_CALL 642 MasterScriptProvider::getElementType( ) 643 { 644 // TODO needs implementing 645 Type t; 646 return t; 647 } 648 649 sal_Bool SAL_CALL MasterScriptProvider::hasElements( ) 650 { 651 // TODO needs implementing 652 throw RuntimeException( "hasElements not implemented!!!!" ); 653 } 654 655 656 OUString SAL_CALL MasterScriptProvider::getImplementationName( ) 657 { 658 return OUString( "com.sun.star.script.provider.MasterScriptProvider" ); 659 } 660 661 sal_Bool SAL_CALL MasterScriptProvider::supportsService( const OUString& serviceName ) 662 { 663 return cppu::supportsService(this, serviceName); 664 } 665 666 667 Sequence< OUString > SAL_CALL MasterScriptProvider::getSupportedServiceNames( ) 668 { 669 OUString names[3]; 670 671 names[0] = "com.sun.star.script.provider.MasterScriptProvider"; 672 names[1] = "com.sun.star.script.browse.BrowseNode"; 673 names[2] = "com.sun.star.script.provider.ScriptProvider"; 674 675 return Sequence< OUString >( names, 3 ); 676 } 677 678 } // namespace func_provider 679 680 681 namespace scripting_runtimemgr 682 { 683 684 static Reference< XInterface > sp_create( 685 const Reference< XComponentContext > & xCompC ) 686 { 687 return static_cast<cppu::OWeakObject *>(new ::func_provider::MasterScriptProvider( xCompC )); 688 } 689 690 691 static Sequence< OUString > sp_getSupportedServiceNames( ) 692 { 693 OUString names[3]; 694 695 names[0] = "com.sun.star.script.provider.MasterScriptProvider"; 696 names[1] = "com.sun.star.script.browse.BrowseNode"; 697 names[2] = "com.sun.star.script.provider.ScriptProvider"; 698 699 return Sequence< OUString >( names, 3 ); 700 } 701 702 703 static OUString sp_getImplementationName( ) 704 { 705 return OUString( "com.sun.star.script.provider.MasterScriptProvider" ); 706 } 707 708 // ***** registration or ScriptingFrameworkURIHelper 709 static Reference< XInterface > urihelper_create( 710 const Reference< XComponentContext > & xCompC ) 711 { 712 return static_cast<cppu::OWeakObject *>( 713 new ::func_provider::ScriptingFrameworkURIHelper( xCompC )); 714 } 715 716 static Sequence< OUString > urihelper_getSupportedServiceNames( ) 717 { 718 OUString serviceNameList[] = { 719 OUString( 720 "com.sun.star.script.provider.ScriptURIHelper" ) }; 721 722 Sequence< OUString > serviceNames = Sequence < 723 OUString > ( serviceNameList, 1 ); 724 725 return serviceNames; 726 } 727 728 static OUString urihelper_getImplementationName( ) 729 { 730 return OUString( 731 "com.sun.star.script.provider.ScriptURIHelper"); 732 } 733 734 static const struct cppu::ImplementationEntry s_entries [] = 735 { 736 { 737 sp_create, sp_getImplementationName, 738 sp_getSupportedServiceNames, cppu::createSingleComponentFactory, 739 nullptr, 0 740 }, 741 { 742 urihelper_create, 743 urihelper_getImplementationName, 744 urihelper_getSupportedServiceNames, 745 cppu::createSingleComponentFactory, 746 nullptr, 0 747 }, 748 { 749 func_provider::mspf_create, func_provider::mspf_getImplementationName, 750 func_provider::mspf_getSupportedServiceNames, cppu::createSingleComponentFactory, 751 nullptr, 0 752 }, 753 { 754 browsenodefactory::bnf_create, browsenodefactory::bnf_getImplementationName, 755 browsenodefactory::bnf_getSupportedServiceNames, cppu::createSingleComponentFactory, 756 nullptr, 0 757 }, 758 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 } 759 }; 760 } 761 762 763 //#### EXPORTED ############################################################## 764 765 766 extern "C" 767 { 768 /** 769 * This function is called to get service factories for an implementation. 770 * 771 * @param pImplName name of implementation 772 * @param pServiceManager a service manager, need for component creation 773 * @param pRegistryKey the registry key for this component, need for persistent 774 * data 775 * @return a component factory 776 */ 777 SAL_DLLPUBLIC_EXPORT void * scriptframe_component_getFactory( 778 const sal_Char * pImplName, 779 void * pServiceManager, 780 void * pRegistryKey ) 781 { 782 return ::cppu::component_getFactoryHelper( pImplName, pServiceManager, 783 pRegistryKey, ::scripting_runtimemgr::s_entries ); 784 } 785 } 786 787 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 788
