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_scripting.hxx" 26 27 #include <cppuhelper/weakref.hxx> 28 #include <cppuhelper/implementationentry.hxx> 29 #include <cppuhelper/factory.hxx> 30 #include <cppuhelper/exc_hlp.hxx> 31 #include <cppuhelper/implbase1.hxx> 32 #include <comphelper/mediadescriptor.hxx> 33 34 #include <com/sun/star/lang/XMultiComponentFactory.hpp> 35 #include <com/sun/star/frame/XModel.hpp> 36 #include <com/sun/star/reflection/XProxyFactory.hpp> 37 38 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp> 39 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp> 40 #include <com/sun/star/document/XScriptInvocationContext.hpp> 41 42 #include <tools/diagnose_ex.h> 43 44 #include "BrowseNodeFactoryImpl.hxx" 45 #include "ActiveMSPList.hxx" 46 #include <util/MiscUtils.hxx> 47 #include <util/util.hxx> 48 49 #include <vector> 50 #include <algorithm> 51 using namespace ::com::sun::star; 52 using namespace ::com::sun::star::uno; 53 using namespace ::com::sun::star::script; 54 using namespace ::sf_misc; 55 56 namespace browsenodefactory 57 { 58 class BrowseNodeAggregator : 59 public ::cppu::WeakImplHelper1< browse::XBrowseNode > 60 { 61 private: 62 ::rtl::OUString m_Name; 63 Sequence< Reference< browse::XBrowseNode > > m_Nodes; 64 65 public: 66 67 BrowseNodeAggregator( const Reference< browse::XBrowseNode >& node ) 68 { 69 m_Name = node->getName(); 70 m_Nodes.realloc( 1 ); 71 m_Nodes[ 0 ] = node; 72 } 73 74 ~BrowseNodeAggregator() 75 { 76 } 77 78 void addBrowseNode( const Reference< browse::XBrowseNode>& node ) 79 { 80 sal_Int32 index = m_Nodes.getLength(); 81 82 m_Nodes.realloc( index + 1 ); 83 m_Nodes[ index ] = node; 84 } 85 86 virtual ::rtl::OUString 87 SAL_CALL getName() 88 { 89 return m_Name; 90 } 91 92 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL 93 getChildNodes() 94 { 95 std::vector< Sequence< Reference < browse::XBrowseNode > > > seqs; 96 seqs.reserve( m_Nodes.getLength() ); 97 98 sal_Int32 numChildren = 0; 99 100 for ( sal_Int32 i = 0; i < m_Nodes.getLength(); i++ ) 101 { 102 Sequence< Reference < browse::XBrowseNode > > childs; 103 try 104 { 105 childs = m_Nodes[ i ]->getChildNodes(); 106 seqs.push_back( childs ); 107 numChildren += childs.getLength(); 108 } 109 catch ( Exception& ) 110 { 111 // some form of exception getting child nodes so they 112 // won't be displayed 113 } 114 } 115 116 std::vector< Sequence< Reference < browse::XBrowseNode > > >::const_iterator it = seqs.begin(); 117 std::vector< Sequence< Reference < browse::XBrowseNode > > >::const_iterator it_end = seqs.end(); 118 119 Sequence< Reference < browse::XBrowseNode > > result( numChildren ); 120 for ( sal_Int32 index = 0; it != it_end && index < numChildren ; ++it ) 121 { 122 Sequence< Reference < browse::XBrowseNode > > childs = *it; 123 for ( sal_Int32 j = 0; j < childs.getLength(); j++ ) 124 { 125 result[ index++ ] = childs[ j ]; 126 } 127 } 128 return result; 129 } 130 131 virtual sal_Bool SAL_CALL 132 hasChildNodes() 133 { 134 if ( m_Nodes.getLength() != 0 ) 135 { 136 for ( sal_Int32 i = 0 ; i < m_Nodes.getLength(); i++ ) 137 { 138 try 139 { 140 if ( m_Nodes[ i ]->hasChildNodes() ) 141 { 142 return sal_True; 143 } 144 } 145 catch ( Exception& ) 146 { 147 // some form of exception getting child nodes so move 148 // on to the next one 149 } 150 } 151 } 152 153 return sal_False; 154 } 155 156 virtual sal_Int16 SAL_CALL getType() 157 { 158 return browse::BrowseNodeTypes::CONTAINER; 159 } 160 }; 161 162 163 //typedef ::std::map< ::rtl::OUString, Reference< browse::XBrowseNode > > 164 typedef ::std::hash_map< ::rtl::OUString, Reference< browse::XBrowseNode >, 165 ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > 166 BrowseNodeAggregatorHash; 167 typedef ::std::vector< ::rtl::OUString > vString; 168 169 170 struct alphaSort 171 { 172 bool operator()( const ::rtl::OUString& a, const ::rtl::OUString& b ) 173 { 174 return a.compareTo( b ) < 0; 175 } 176 }; 177 class LocationBrowseNode : 178 public ::cppu::WeakImplHelper1< browse::XBrowseNode > 179 { 180 private: 181 BrowseNodeAggregatorHash* m_hBNA; 182 vString m_vStr; 183 ::rtl::OUString m_sNodeName; 184 Reference< browse::XBrowseNode > m_origNode; 185 186 public: 187 188 LocationBrowseNode( const Reference< browse::XBrowseNode >& node ) 189 { 190 m_sNodeName = node->getName(); 191 m_hBNA = NULL; 192 m_origNode.set( node ); 193 } 194 195 ~LocationBrowseNode() 196 { 197 if (m_hBNA) 198 { 199 delete m_hBNA; 200 } 201 } 202 203 // ------------------------------------------------------------------------- 204 // XBrowseNode 205 // ------------------------------------------------------------------------- 206 207 virtual ::rtl::OUString SAL_CALL getName() 208 { 209 return m_sNodeName; 210 } 211 212 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL 213 getChildNodes() 214 { 215 if ( m_hBNA == NULL ) 216 { 217 loadChildNodes(); 218 } 219 220 Sequence< Reference< browse::XBrowseNode > > children( m_hBNA->size() ); 221 sal_Int32 index = 0; 222 223 vString::const_iterator it = m_vStr.begin(); 224 225 for ( ; it != m_vStr.end(); ++it, index++ ) 226 { 227 children[ index ].set( m_hBNA->find( *it )->second ); 228 } 229 230 return children; 231 } 232 233 virtual sal_Bool SAL_CALL hasChildNodes() 234 { 235 return sal_True; 236 } 237 238 virtual sal_Int16 SAL_CALL getType() 239 { 240 return browse::BrowseNodeTypes::CONTAINER; 241 } 242 243 private: 244 245 void loadChildNodes() 246 { 247 m_hBNA = new BrowseNodeAggregatorHash(); 248 249 Sequence< Reference< browse::XBrowseNode > > langNodes = 250 m_origNode->getChildNodes(); 251 252 for ( sal_Int32 i = 0; i < langNodes.getLength(); i++ ) 253 { 254 Reference< browse::XBrowseNode > xbn; 255 if ( langNodes[ i ]->getName().equals(::rtl::OUString::createFromAscii("uno_packages")) ) 256 { 257 xbn.set( new LocationBrowseNode( langNodes[ i ] ) ); 258 } 259 else 260 { 261 xbn.set( langNodes[ i ] ); 262 } 263 264 Sequence< Reference< browse::XBrowseNode > > grandchildren = 265 xbn->getChildNodes(); 266 267 for ( sal_Int32 j = 0; j < grandchildren.getLength(); j++ ) 268 { 269 Reference< browse::XBrowseNode > grandchild(grandchildren[j]); 270 271 BrowseNodeAggregatorHash::iterator h_it = 272 m_hBNA->find( grandchild->getName() ); 273 274 if ( h_it != m_hBNA->end() ) 275 { 276 BrowseNodeAggregator* bna = static_cast< BrowseNodeAggregator* >( h_it->second.get() ); 277 bna->addBrowseNode( grandchild ); 278 } 279 else 280 { 281 Reference< browse::XBrowseNode > bna( 282 new BrowseNodeAggregator( grandchild ) ); 283 (*m_hBNA)[ grandchild->getName() ].set( bna ); 284 m_vStr.push_back( grandchild->getName() ); 285 } 286 } 287 } 288 // sort children alphabetically 289 ::std::sort( m_vStr.begin(), m_vStr.end(), alphaSort() ); 290 } 291 }; 292 293 namespace 294 { 295 296 Sequence< Reference< browse::XBrowseNode > > getAllBrowseNodes( const Reference< XComponentContext >& xCtx ) 297 { 298 Reference< lang::XMultiComponentFactory > mcf = 299 xCtx->getServiceManager(); 300 301 Sequence< ::rtl::OUString > openDocs = 302 MiscUtils::allOpenTDocUrls( xCtx ); 303 304 Reference< provider::XScriptProviderFactory > xFac; 305 sal_Int32 initialSize = openDocs.getLength() + 2; 306 sal_Int32 mspIndex = 0; 307 308 Sequence < Reference < browse::XBrowseNode > > locnBNs( initialSize ); 309 try 310 { 311 xFac.set( 312 xCtx->getValueByName( 313 OUSTR("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY_THROW ); 314 315 locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( xFac->createScriptProvider( makeAny( ::rtl::OUString::createFromAscii("user") ) ), UNO_QUERY_THROW ); 316 locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( xFac->createScriptProvider( makeAny( ::rtl::OUString::createFromAscii("share") ) ), UNO_QUERY_THROW ); 317 } 318 // TODO proper exception handling, should throw 319 catch( Exception& e ) 320 { 321 (void)e; 322 OSL_TRACE("Caught Exception %s", 323 ::rtl::OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).pData->buffer ); 324 locnBNs.realloc( mspIndex ); 325 return locnBNs; 326 } 327 328 for ( sal_Int32 i = 0; i < openDocs.getLength(); i++ ) 329 { 330 try 331 { 332 Reference< frame::XModel > model( MiscUtils::tDocUrlToModel( openDocs[ i ] ), UNO_QUERY_THROW ); 333 334 // #i44599 Check if it's a real document or something special like Hidden/Preview 335 css::uno::Reference< css::frame::XController > xCurrentController = model->getCurrentController(); 336 if( xCurrentController.is() ) 337 { 338 comphelper::MediaDescriptor aMD( model->getArgs() ); 339 sal_Bool bDefault = false; 340 sal_Bool bHidden = aMD.getUnpackedValueOrDefault( comphelper::MediaDescriptor::PROP_HIDDEN(), bDefault ); 341 sal_Bool bPreview = aMD.getUnpackedValueOrDefault( comphelper::MediaDescriptor::PROP_PREVIEW(), bDefault ); 342 if( !bHidden && !bPreview ) 343 { 344 Reference< document::XEmbeddedScripts > xScripts( model, UNO_QUERY ); 345 if ( xScripts.is() ) 346 locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( 347 xFac->createScriptProvider( makeAny( model ) ), UNO_QUERY_THROW ); 348 } 349 } 350 } 351 catch( const Exception& ) 352 { 353 DBG_UNHANDLED_EXCEPTION(); 354 } 355 356 } 357 358 Sequence < Reference < browse::XBrowseNode > > locnBNs_Return( mspIndex ); 359 for ( sal_Int32 j = 0; j < mspIndex; j++ ) 360 locnBNs_Return[j] = locnBNs[j]; 361 362 return locnBNs_Return; 363 } 364 365 } // namespace 366 367 typedef ::std::vector< Reference< browse::XBrowseNode > > vXBrowseNodes; 368 369 struct alphaSortForBNodes 370 { 371 bool operator()( const Reference< browse::XBrowseNode >& a, const Reference< browse::XBrowseNode >& b ) 372 { 373 return a->getName().compareTo( b->getName() ) < 0; 374 } 375 }; 376 377 typedef ::cppu::WeakImplHelper1< browse::XBrowseNode > t_BrowseNodeBase; 378 class DefaultBrowseNode : 379 public t_BrowseNodeBase 380 { 381 382 private: 383 Reference< browse::XBrowseNode > m_xWrappedBrowseNode; 384 Reference< lang::XTypeProvider > m_xWrappedTypeProv; 385 Reference< XAggregation > m_xAggProxy; 386 Reference< XComponentContext > m_xCtx; 387 388 DefaultBrowseNode(); 389 public: 390 DefaultBrowseNode( const Reference< XComponentContext >& xCtx, const Reference< browse::XBrowseNode>& xNode ) : m_xWrappedBrowseNode( xNode ), m_xWrappedTypeProv( xNode, UNO_QUERY ), m_xCtx( xCtx, UNO_QUERY ) 391 { 392 OSL_ENSURE( m_xWrappedBrowseNode.is(), "DefaultBrowseNode::DefaultBrowseNode(): No BrowseNode to wrap" ); 393 OSL_ENSURE( m_xWrappedTypeProv.is(), "DefaultBrowseNode::DefaultBrowseNode(): No BrowseNode to wrap" ); 394 OSL_ENSURE( m_xCtx.is(), "DefaultBrowseNode::DefaultBrowseNode(): No ComponentContext" ); 395 // Use proxy factory service to create aggregatable proxy. 396 try 397 { 398 Reference< lang::XMultiComponentFactory > xMFac( m_xCtx->getServiceManager(), UNO_QUERY_THROW ); 399 Reference< reflection::XProxyFactory > xProxyFac( 400 xMFac->createInstanceWithContext( 401 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 402 "com.sun.star.reflection.ProxyFactory" ) ), 403 m_xCtx ), UNO_QUERY_THROW ); 404 m_xAggProxy = xProxyFac->createProxy( m_xWrappedBrowseNode ); 405 } 406 catch( uno::Exception& ) 407 { 408 OSL_ENSURE( false, "DefaultBrowseNode::DefaultBrowseNode: Caught exception!" ); 409 } 410 OSL_ENSURE( m_xAggProxy.is(), 411 "DefaultBrowseNode::DefaultBrowseNode: Wrapped BrowseNode cannot be aggregated!" ); 412 413 if ( m_xAggProxy.is() ) 414 { 415 osl_incrementInterlockedCount( &m_refCount ); 416 417 /* i35609 - Fix crash on Solaris. The setDelegator call needs 418 to be in its own block to ensure that all temporary Reference 419 instances that are acquired during the call are released 420 before m_refCount is decremented again */ 421 { 422 m_xAggProxy->setDelegator( 423 static_cast< cppu::OWeakObject * >( this ) ); 424 } 425 426 osl_decrementInterlockedCount( &m_refCount ); 427 } 428 } 429 430 ~DefaultBrowseNode() 431 { 432 if ( m_xAggProxy.is() ) 433 { 434 m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() ); 435 } 436 } 437 438 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL 439 getChildNodes() 440 { 441 if ( hasChildNodes() ) 442 { 443 vXBrowseNodes m_vNodes; 444 Sequence < Reference< browse::XBrowseNode > > nodes = 445 m_xWrappedBrowseNode->getChildNodes(); 446 for ( sal_Int32 i=0; i<nodes.getLength(); i++ ) 447 { 448 Reference< browse::XBrowseNode > xBrowseNode = nodes[ i ]; 449 OSL_ENSURE( xBrowseNode.is(), "DefaultBrowseNode::getChildNodes(): Invalid BrowseNode" ); 450 if( xBrowseNode.is() ) 451 m_vNodes.push_back( new DefaultBrowseNode( m_xCtx, xBrowseNode ) ); 452 } 453 454 ::std::sort( m_vNodes.begin(), m_vNodes.end(), alphaSortForBNodes() ); 455 Sequence < Reference< browse::XBrowseNode > > children( m_vNodes.size() ); 456 vXBrowseNodes::const_iterator it = m_vNodes.begin(); 457 for ( sal_Int32 i=0; it != m_vNodes.end() && i<children.getLength(); i++, ++it ) 458 { 459 children[ i ].set( *it ); 460 } 461 return children; 462 } 463 else 464 { 465 // no nodes 466 467 Sequence < Reference< browse::XBrowseNode > > none; 468 return none; 469 } 470 } 471 472 virtual sal_Int16 SAL_CALL getType() 473 { 474 return m_xWrappedBrowseNode->getType(); 475 } 476 477 virtual ::rtl::OUString 478 SAL_CALL getName() 479 { 480 return m_xWrappedBrowseNode->getName(); 481 } 482 483 virtual sal_Bool SAL_CALL 484 hasChildNodes() 485 { 486 return m_xWrappedBrowseNode->hasChildNodes(); 487 } 488 489 // XInterface 490 virtual Any SAL_CALL queryInterface( const Type& aType ) 491 { 492 Any aRet = t_BrowseNodeBase::queryInterface( aType ); 493 if ( aRet.hasValue() ) 494 { 495 return aRet; 496 } 497 if ( m_xAggProxy.is() ) 498 { 499 return m_xAggProxy->queryAggregation( aType ); 500 } 501 else 502 { 503 return Any(); 504 } 505 } 506 507 virtual void SAL_CALL acquire() 508 throw () 509 510 { 511 osl_incrementInterlockedCount( &m_refCount ); 512 } 513 virtual void SAL_CALL release() 514 throw () 515 { 516 if ( osl_decrementInterlockedCount( &m_refCount ) == 0 ) 517 { 518 delete this; 519 } 520 } 521 // XTypeProvider (implemnented by base, but needs to be overridden for 522 // delegating to aggregate) 523 virtual Sequence< Type > SAL_CALL getTypes() 524 { 525 return m_xWrappedTypeProv->getTypes(); 526 } 527 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() 528 { 529 return m_xWrappedTypeProv->getImplementationId(); 530 531 } 532 }; 533 534 class DefaultRootBrowseNode : 535 public ::cppu::WeakImplHelper1< browse::XBrowseNode > 536 { 537 538 private: 539 vXBrowseNodes m_vNodes; 540 ::rtl::OUString m_Name; 541 542 DefaultRootBrowseNode(); 543 public: 544 DefaultRootBrowseNode( const Reference< XComponentContext >& xCtx ) 545 { 546 Sequence < Reference< browse::XBrowseNode > > nodes = 547 getAllBrowseNodes( xCtx ); 548 549 for ( sal_Int32 i=0; i<nodes.getLength(); i++ ) 550 { 551 m_vNodes.push_back( new DefaultBrowseNode( xCtx, nodes[ i ] ) ); 552 } 553 m_Name = ::rtl::OUString::createFromAscii( "Root" ); 554 } 555 556 ~DefaultRootBrowseNode() 557 { 558 } 559 560 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL 561 getChildNodes() 562 { 563 // no need to sort user, share, doc1...docN 564 //::std::sort( m_vNodes.begin(), m_vNodes.end(), alphaSortForBNodes() ); 565 Sequence < Reference< browse::XBrowseNode > > children( m_vNodes.size() ); 566 vXBrowseNodes::const_iterator it = m_vNodes.begin(); 567 for ( sal_Int32 i=0; it != m_vNodes.end() && i<children.getLength(); i++, ++it ) 568 { 569 children[ i ].set( *it ); 570 } 571 return children; 572 } 573 574 virtual sal_Int16 SAL_CALL getType() 575 { 576 return browse::BrowseNodeTypes::ROOT; 577 } 578 579 virtual ::rtl::OUString 580 SAL_CALL getName() 581 { 582 return m_Name; 583 } 584 585 virtual sal_Bool SAL_CALL 586 hasChildNodes() 587 { 588 sal_Bool result = sal_True; 589 if ( !m_vNodes.size() ) 590 { 591 result = sal_False; 592 } 593 return result; 594 } 595 }; 596 597 598 class SelectorBrowseNode : 599 public ::cppu::WeakImplHelper1< browse::XBrowseNode > 600 { 601 private: 602 Reference< XComponentContext > m_xComponentContext; 603 604 public: 605 SelectorBrowseNode( const Reference< XComponentContext >& xContext ) 606 : m_xComponentContext( xContext ) 607 { 608 } 609 610 ~SelectorBrowseNode() 611 { 612 } 613 614 virtual ::rtl::OUString SAL_CALL getName() 615 { 616 return ::rtl::OUString::createFromAscii( "Root" ); 617 } 618 619 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL 620 getChildNodes() 621 { 622 623 Sequence < Reference < browse::XBrowseNode > > locnBNs = getAllBrowseNodes( m_xComponentContext ); 624 625 Sequence< Reference< browse::XBrowseNode > > children( 626 locnBNs.getLength() ); 627 628 for ( sal_Int32 j = 0; j < locnBNs.getLength(); j++ ) 629 { 630 children[j] = new LocationBrowseNode( locnBNs[j] ); 631 } 632 633 return children; 634 } 635 636 virtual sal_Bool SAL_CALL hasChildNodes() 637 { 638 return sal_True; // will always be user and share 639 } 640 641 virtual sal_Int16 SAL_CALL getType() 642 { 643 return browse::BrowseNodeTypes::CONTAINER; 644 } 645 }; 646 647 BrowseNodeFactoryImpl::BrowseNodeFactoryImpl( 648 Reference< XComponentContext > const & xComponentContext ) 649 : m_xComponentContext( xComponentContext ) 650 { 651 } 652 653 BrowseNodeFactoryImpl::~BrowseNodeFactoryImpl() 654 { 655 } 656 657 658 //############################################################################ 659 // Implementation of XBrowseNodeFactory 660 //############################################################################ 661 662 /* 663 * The selector hierarchy is the standard hierarchy for organizers with the 664 * language nodes removed. 665 */ 666 Reference< browse::XBrowseNode > SAL_CALL 667 BrowseNodeFactoryImpl::createView( sal_Int16 viewType ) 668 { 669 switch( viewType ) 670 { 671 case browse::BrowseNodeFactoryViewTypes::MACROSELECTOR: 672 return getSelectorHierarchy(); 673 case browse::BrowseNodeFactoryViewTypes::MACROORGANIZER: 674 return getOrganizerHierarchy(); 675 default: 676 throw RuntimeException( OUSTR("Unknown view type" ), Reference< XInterface >() ); 677 } 678 } 679 680 Reference< browse::XBrowseNode > 681 BrowseNodeFactoryImpl::getSelectorHierarchy() 682 { 683 /*if ( !m_xSelectorBrowseNode.is() ) 684 { 685 m_xSelectorBrowseNode = new SelectorBrowseNode( m_xComponentContext ); 686 }*/ 687 return new SelectorBrowseNode( m_xComponentContext ); 688 } 689 690 Reference< browse::XBrowseNode > 691 BrowseNodeFactoryImpl::getOrganizerHierarchy() 692 { 693 Reference< browse::XBrowseNode > xRet = new DefaultRootBrowseNode( m_xComponentContext ); 694 return xRet; 695 } 696 //############################################################################ 697 // Helper methods 698 //############################################################################ 699 700 //############################################################################ 701 // Namespace global methods for setting up BrowseNodeFactory service 702 //############################################################################ 703 704 Sequence< ::rtl::OUString > SAL_CALL 705 bnf_getSupportedServiceNames( ) 706 SAL_THROW( () ) 707 { 708 ::rtl::OUString str_name = ::rtl::OUString::createFromAscii( 709 "com.sun.star.script.browse.BrowseNodeFactory"); 710 711 return Sequence< ::rtl::OUString >( &str_name, 1 ); 712 } 713 714 ::rtl::OUString SAL_CALL 715 bnf_getImplementationName( ) 716 SAL_THROW( () ) 717 { 718 return ::rtl::OUString::createFromAscii( 719 "com.sun.star.script.browse.BrowseNodeFactory" ); 720 } 721 722 Reference< XInterface > SAL_CALL 723 bnf_create( Reference< XComponentContext > const & xComponentContext ) 724 { 725 return static_cast< ::cppu::OWeakObject * >( 726 new BrowseNodeFactoryImpl( xComponentContext ) ); 727 } 728 729 //############################################################################ 730 // Implementation of XServiceInfo 731 //############################################################################ 732 733 ::rtl::OUString SAL_CALL 734 BrowseNodeFactoryImpl::getImplementationName() 735 { 736 return bnf_getImplementationName(); 737 } 738 739 Sequence< ::rtl::OUString > SAL_CALL 740 BrowseNodeFactoryImpl::getSupportedServiceNames() 741 { 742 return bnf_getSupportedServiceNames(); 743 } 744 745 sal_Bool BrowseNodeFactoryImpl::supportsService( 746 ::rtl::OUString const & serviceName ) 747 { 748 // check(); 749 750 Sequence< ::rtl::OUString > supported_services( 751 getSupportedServiceNames() ); 752 753 ::rtl::OUString const * ar = supported_services.getConstArray(); 754 755 for ( sal_Int32 pos = supported_services.getLength(); pos--; ) 756 { 757 if (ar[ pos ].equals( serviceName )) 758 return sal_True; 759 } 760 return sal_False; 761 } 762 763 } // namespace browsenodefactory 764