merge the formfield patch from ooo-build
[ooovba.git] / scripting / source / provider / BrowseNodeFactoryImpl.cxx
blob9dd4de69bbcddc2e4d303c723515d355dd8eb10a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: BrowseNodeFactoryImpl.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_scripting.hxx"
34 #include <cppuhelper/weakref.hxx>
35 #include <cppuhelper/implementationentry.hxx>
36 #include <cppuhelper/factory.hxx>
37 #include <cppuhelper/exc_hlp.hxx>
38 #include <cppuhelper/implbase1.hxx>
39 #include <comphelper/mediadescriptor.hxx>
41 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
42 #include <com/sun/star/frame/XModel.hpp>
43 #include <com/sun/star/reflection/XProxyFactory.hpp>
45 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
46 #include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
47 #include <com/sun/star/document/XScriptInvocationContext.hpp>
49 #include <tools/diagnose_ex.h>
51 #include "BrowseNodeFactoryImpl.hxx"
52 #include "ActiveMSPList.hxx"
53 #include <util/MiscUtils.hxx>
54 #include <util/util.hxx>
56 #include <vector>
57 #include <algorithm>
58 using namespace ::com::sun::star;
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::script;
61 using namespace ::sf_misc;
63 namespace browsenodefactory
65 class BrowseNodeAggregator :
66 public ::cppu::WeakImplHelper1< browse::XBrowseNode >
68 private:
69 ::rtl::OUString m_Name;
70 Sequence< Reference< browse::XBrowseNode > > m_Nodes;
72 public:
74 BrowseNodeAggregator( const Reference< browse::XBrowseNode >& node )
76 m_Name = node->getName();
77 m_Nodes.realloc( 1 );
78 m_Nodes[ 0 ] = node;
81 ~BrowseNodeAggregator()
85 void addBrowseNode( const Reference< browse::XBrowseNode>& node )
87 sal_Int32 index = m_Nodes.getLength();
89 m_Nodes.realloc( index + 1 );
90 m_Nodes[ index ] = node;
93 virtual ::rtl::OUString
94 SAL_CALL getName()
95 throw ( RuntimeException )
97 return m_Name;
100 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL
101 getChildNodes()
102 throw ( RuntimeException )
104 std::vector< Sequence< Reference < browse::XBrowseNode > > > seqs;
105 seqs.reserve( m_Nodes.getLength() );
107 sal_Int32 numChildren = 0;
109 for ( sal_Int32 i = 0; i < m_Nodes.getLength(); i++ )
111 Sequence< Reference < browse::XBrowseNode > > childs;
114 childs = m_Nodes[ i ]->getChildNodes();
115 seqs.push_back( childs );
116 numChildren += childs.getLength();
118 catch ( Exception& )
120 // some form of exception getting child nodes so they
121 // won't be displayed
125 std::vector< Sequence< Reference < browse::XBrowseNode > > >::const_iterator it = seqs.begin();
126 std::vector< Sequence< Reference < browse::XBrowseNode > > >::const_iterator it_end = seqs.end();
128 Sequence< Reference < browse::XBrowseNode > > result( numChildren );
129 for ( sal_Int32 index = 0; it != it_end && index < numChildren ; ++it )
131 Sequence< Reference < browse::XBrowseNode > > childs = *it;
132 for ( sal_Int32 j = 0; j < childs.getLength(); j++ )
134 result[ index++ ] = childs[ j ];
137 return result;
140 virtual sal_Bool SAL_CALL
141 hasChildNodes()
142 throw ( RuntimeException )
144 if ( m_Nodes.getLength() != 0 )
146 for ( sal_Int32 i = 0 ; i < m_Nodes.getLength(); i++ )
150 if ( m_Nodes[ i ]->hasChildNodes() )
152 return sal_True;
155 catch ( Exception& )
157 // some form of exception getting child nodes so move
158 // on to the next one
163 return sal_False;
166 virtual sal_Int16 SAL_CALL getType()
167 throw ( RuntimeException )
169 return browse::BrowseNodeTypes::CONTAINER;
174 //typedef ::std::map< ::rtl::OUString, Reference< browse::XBrowseNode > >
175 typedef ::std::hash_map< ::rtl::OUString, Reference< browse::XBrowseNode >,
176 ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > >
177 BrowseNodeAggregatorHash;
178 typedef ::std::vector< ::rtl::OUString > vString;
181 struct alphaSort
183 bool operator()( const ::rtl::OUString& a, const ::rtl::OUString& b )
185 return a.compareTo( b ) < 0;
188 class LocationBrowseNode :
189 public ::cppu::WeakImplHelper1< browse::XBrowseNode >
191 private:
192 BrowseNodeAggregatorHash* m_hBNA;
193 vString m_vStr;
194 ::rtl::OUString m_sNodeName;
195 Reference< browse::XBrowseNode > m_origNode;
197 public:
199 LocationBrowseNode( const Reference< browse::XBrowseNode >& node )
201 m_sNodeName = node->getName();
202 m_hBNA = NULL;
203 m_origNode.set( node );
206 ~LocationBrowseNode()
208 if (m_hBNA)
210 delete m_hBNA;
214 // -------------------------------------------------------------------------
215 // XBrowseNode
216 // -------------------------------------------------------------------------
218 virtual ::rtl::OUString SAL_CALL getName()
219 throw ( RuntimeException )
221 return m_sNodeName;
224 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL
225 getChildNodes()
226 throw ( RuntimeException )
228 if ( m_hBNA == NULL )
230 loadChildNodes();
233 Sequence< Reference< browse::XBrowseNode > > children( m_hBNA->size() );
234 sal_Int32 index = 0;
236 vString::const_iterator it = m_vStr.begin();
238 for ( ; it != m_vStr.end(); ++it, index++ )
240 children[ index ].set( m_hBNA->find( *it )->second );
243 return children;
246 virtual sal_Bool SAL_CALL hasChildNodes()
247 throw ( RuntimeException )
249 return sal_True;
252 virtual sal_Int16 SAL_CALL getType()
253 throw ( RuntimeException )
255 return browse::BrowseNodeTypes::CONTAINER;
258 private:
260 void loadChildNodes()
262 m_hBNA = new BrowseNodeAggregatorHash();
264 Sequence< Reference< browse::XBrowseNode > > langNodes =
265 m_origNode->getChildNodes();
267 for ( sal_Int32 i = 0; i < langNodes.getLength(); i++ )
269 Reference< browse::XBrowseNode > xbn;
270 if ( langNodes[ i ]->getName().equals(::rtl::OUString::createFromAscii("uno_packages")) )
272 xbn.set( new LocationBrowseNode( langNodes[ i ] ) );
274 else
276 xbn.set( langNodes[ i ] );
279 Sequence< Reference< browse::XBrowseNode > > grandchildren =
280 xbn->getChildNodes();
282 for ( sal_Int32 j = 0; j < grandchildren.getLength(); j++ )
284 Reference< browse::XBrowseNode > grandchild(grandchildren[j]);
286 BrowseNodeAggregatorHash::iterator h_it =
287 m_hBNA->find( grandchild->getName() );
289 if ( h_it != m_hBNA->end() )
291 BrowseNodeAggregator* bna = static_cast< BrowseNodeAggregator* >( h_it->second.get() );
292 bna->addBrowseNode( grandchild );
294 else
296 Reference< browse::XBrowseNode > bna(
297 new BrowseNodeAggregator( grandchild ) );
298 (*m_hBNA)[ grandchild->getName() ].set( bna );
299 m_vStr.push_back( grandchild->getName() );
303 // sort children alpahbetically
304 ::std::sort( m_vStr.begin(), m_vStr.end(), alphaSort() );
308 namespace
311 Sequence< Reference< browse::XBrowseNode > > getAllBrowseNodes( const Reference< XComponentContext >& xCtx )
313 Reference< lang::XMultiComponentFactory > mcf =
314 xCtx->getServiceManager();
316 Sequence< ::rtl::OUString > openDocs =
317 MiscUtils::allOpenTDocUrls( xCtx );
319 Reference< provider::XScriptProviderFactory > xFac;
320 sal_Int32 initialSize = openDocs.getLength() + 2;
321 sal_Int32 mspIndex = 0;
323 Sequence < Reference < browse::XBrowseNode > > locnBNs( initialSize );
326 xFac.set(
327 xCtx->getValueByName(
328 OUSTR("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY_THROW );
330 locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( xFac->createScriptProvider( makeAny( ::rtl::OUString::createFromAscii("user") ) ), UNO_QUERY_THROW );
331 locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >( xFac->createScriptProvider( makeAny( ::rtl::OUString::createFromAscii("share") ) ), UNO_QUERY_THROW );
333 // TODO proper exception handling, should throw
334 catch( Exception& e )
336 (void)e;
337 OSL_TRACE("Caught Exception %s",
338 ::rtl::OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ).pData->buffer );
339 locnBNs.realloc( mspIndex );
340 return locnBNs;
343 for ( sal_Int32 i = 0; i < openDocs.getLength(); i++ )
347 Reference< frame::XModel > model( MiscUtils::tDocUrlToModel( openDocs[ i ] ), UNO_QUERY_THROW );
349 // #i44599 Check if it's a real document or something special like Hidden/Preview
350 css::uno::Reference< css::frame::XController > xCurrentController = model->getCurrentController();
351 if( xCurrentController.is() )
353 comphelper::MediaDescriptor aMD( model->getArgs() );
354 sal_Bool bDefault = false;
355 sal_Bool bHidden = aMD.getUnpackedValueOrDefault( comphelper::MediaDescriptor::PROP_HIDDEN(), bDefault );
356 sal_Bool bPreview = aMD.getUnpackedValueOrDefault( comphelper::MediaDescriptor::PROP_PREVIEW(), bDefault );
357 if( !bHidden && !bPreview )
359 Reference< document::XEmbeddedScripts > xScripts( model, UNO_QUERY );
360 if ( xScripts.is() )
361 locnBNs[ mspIndex++ ] = Reference< browse::XBrowseNode >(
362 xFac->createScriptProvider( makeAny( model ) ), UNO_QUERY_THROW );
366 catch( const Exception& )
368 DBG_UNHANDLED_EXCEPTION();
373 Sequence < Reference < browse::XBrowseNode > > locnBNs_Return( mspIndex );
374 for ( sal_Int32 j = 0; j < mspIndex; j++ )
375 locnBNs_Return[j] = locnBNs[j];
377 return locnBNs_Return;
380 } // namespace
382 typedef ::std::vector< Reference< browse::XBrowseNode > > vXBrowseNodes;
384 struct alphaSortForBNodes
386 bool operator()( const Reference< browse::XBrowseNode >& a, const Reference< browse::XBrowseNode >& b )
388 return a->getName().compareTo( b->getName() ) < 0;
392 typedef ::cppu::WeakImplHelper1< browse::XBrowseNode > t_BrowseNodeBase;
393 class DefaultBrowseNode :
394 public t_BrowseNodeBase
397 private:
398 Reference< browse::XBrowseNode > m_xWrappedBrowseNode;
399 Reference< lang::XTypeProvider > m_xWrappedTypeProv;
400 Reference< XAggregation > m_xAggProxy;
401 Reference< XComponentContext > m_xCtx;
403 DefaultBrowseNode();
404 public:
405 DefaultBrowseNode( const Reference< XComponentContext >& xCtx, const Reference< browse::XBrowseNode>& xNode ) : m_xWrappedBrowseNode( xNode ), m_xWrappedTypeProv( xNode, UNO_QUERY ), m_xCtx( xCtx, UNO_QUERY )
407 OSL_ENSURE( m_xWrappedBrowseNode.is(), "DefaultBrowseNode::DefaultBrowseNode(): No BrowseNode to wrap" );
408 OSL_ENSURE( m_xWrappedTypeProv.is(), "DefaultBrowseNode::DefaultBrowseNode(): No BrowseNode to wrap" );
409 OSL_ENSURE( m_xCtx.is(), "DefaultBrowseNode::DefaultBrowseNode(): No ComponentContext" );
410 // Use proxy factory service to create aggregatable proxy.
413 Reference< lang::XMultiComponentFactory > xMFac( m_xCtx->getServiceManager(), UNO_QUERY_THROW );
414 Reference< reflection::XProxyFactory > xProxyFac(
415 xMFac->createInstanceWithContext(
416 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
417 "com.sun.star.reflection.ProxyFactory" ) ),
418 m_xCtx ), UNO_QUERY_THROW );
419 m_xAggProxy = xProxyFac->createProxy( m_xWrappedBrowseNode );
421 catch( uno::Exception& )
423 OSL_ENSURE( false, "DefaultBrowseNode::DefaultBrowseNode: Caught exception!" );
425 OSL_ENSURE( m_xAggProxy.is(),
426 "DefaultBrowseNode::DefaultBrowseNode: Wrapped BrowseNode cannot be aggregated!" );
428 if ( m_xAggProxy.is() )
430 osl_incrementInterlockedCount( &m_refCount );
432 /* i35609 - Fix crash on Solaris. The setDelegator call needs
433 to be in its own block to ensure that all temporary Reference
434 instances that are acquired during the call are released
435 before m_refCount is decremented again */
437 m_xAggProxy->setDelegator(
438 static_cast< cppu::OWeakObject * >( this ) );
441 osl_decrementInterlockedCount( &m_refCount );
445 ~DefaultBrowseNode()
447 if ( m_xAggProxy.is() )
449 m_xAggProxy->setDelegator( uno::Reference< uno::XInterface >() );
453 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL
454 getChildNodes()
455 throw ( RuntimeException )
457 if ( hasChildNodes() )
459 vXBrowseNodes m_vNodes;
460 Sequence < Reference< browse::XBrowseNode > > nodes =
461 m_xWrappedBrowseNode->getChildNodes();
462 for ( sal_Int32 i=0; i<nodes.getLength(); i++ )
464 Reference< browse::XBrowseNode > xBrowseNode = nodes[ i ];
465 OSL_ENSURE( xBrowseNode.is(), "DefaultBrowseNode::getChildNodes(): Invalid BrowseNode" );
466 if( xBrowseNode.is() )
467 m_vNodes.push_back( new DefaultBrowseNode( m_xCtx, xBrowseNode ) );
470 ::std::sort( m_vNodes.begin(), m_vNodes.end(), alphaSortForBNodes() );
471 Sequence < Reference< browse::XBrowseNode > > children( m_vNodes.size() );
472 vXBrowseNodes::const_iterator it = m_vNodes.begin();
473 for ( sal_Int32 i=0; it != m_vNodes.end() && i<children.getLength(); i++, ++it )
475 children[ i ].set( *it );
477 return children;
479 else
481 // no nodes
483 Sequence < Reference< browse::XBrowseNode > > none;
484 return none;
488 virtual sal_Int16 SAL_CALL getType()
489 throw ( RuntimeException )
491 return m_xWrappedBrowseNode->getType();
494 virtual ::rtl::OUString
495 SAL_CALL getName()
496 throw ( RuntimeException )
498 return m_xWrappedBrowseNode->getName();
501 virtual sal_Bool SAL_CALL
502 hasChildNodes()
503 throw ( RuntimeException )
505 return m_xWrappedBrowseNode->hasChildNodes();
508 // XInterface
509 virtual Any SAL_CALL queryInterface( const Type& aType )
510 throw ( com::sun::star::uno::RuntimeException )
512 Any aRet = t_BrowseNodeBase::queryInterface( aType );
513 if ( aRet.hasValue() )
515 return aRet;
517 if ( m_xAggProxy.is() )
519 return m_xAggProxy->queryAggregation( aType );
521 else
523 return Any();
527 virtual void SAL_CALL acquire()
528 throw ()
531 osl_incrementInterlockedCount( &m_refCount );
533 virtual void SAL_CALL release()
534 throw ()
536 if ( osl_decrementInterlockedCount( &m_refCount ) == 0 )
538 delete this;
541 // XTypeProvider (implemnented by base, but needs to be overridden for
542 // delegating to aggregate)
543 virtual Sequence< Type > SAL_CALL getTypes()
544 throw ( com::sun::star::uno::RuntimeException )
546 return m_xWrappedTypeProv->getTypes();
548 virtual Sequence< sal_Int8 > SAL_CALL getImplementationId()
549 throw ( com::sun::star::uno::RuntimeException )
551 return m_xWrappedTypeProv->getImplementationId();
556 class DefaultRootBrowseNode :
557 public ::cppu::WeakImplHelper1< browse::XBrowseNode >
560 private:
561 vXBrowseNodes m_vNodes;
562 ::rtl::OUString m_Name;
564 DefaultRootBrowseNode();
565 public:
566 DefaultRootBrowseNode( const Reference< XComponentContext >& xCtx )
568 Sequence < Reference< browse::XBrowseNode > > nodes =
569 getAllBrowseNodes( xCtx );
571 for ( sal_Int32 i=0; i<nodes.getLength(); i++ )
573 m_vNodes.push_back( new DefaultBrowseNode( xCtx, nodes[ i ] ) );
575 m_Name = ::rtl::OUString::createFromAscii( "Root" );
578 ~DefaultRootBrowseNode()
582 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL
583 getChildNodes()
584 throw ( RuntimeException )
586 // no need to sort user, share, doc1...docN
587 //::std::sort( m_vNodes.begin(), m_vNodes.end(), alphaSortForBNodes() );
588 Sequence < Reference< browse::XBrowseNode > > children( m_vNodes.size() );
589 vXBrowseNodes::const_iterator it = m_vNodes.begin();
590 for ( sal_Int32 i=0; it != m_vNodes.end() && i<children.getLength(); i++, ++it )
592 children[ i ].set( *it );
594 return children;
597 virtual sal_Int16 SAL_CALL getType()
598 throw ( RuntimeException )
600 return browse::BrowseNodeTypes::ROOT;
603 virtual ::rtl::OUString
604 SAL_CALL getName()
605 throw ( RuntimeException )
607 return m_Name;
610 virtual sal_Bool SAL_CALL
611 hasChildNodes()
612 throw ( RuntimeException )
614 sal_Bool result = sal_True;
615 if ( !m_vNodes.size() )
617 result = sal_False;
619 return result;
624 class SelectorBrowseNode :
625 public ::cppu::WeakImplHelper1< browse::XBrowseNode >
627 private:
628 Reference< XComponentContext > m_xComponentContext;
630 public:
631 SelectorBrowseNode( const Reference< XComponentContext >& xContext )
632 : m_xComponentContext( xContext )
636 ~SelectorBrowseNode()
640 virtual ::rtl::OUString SAL_CALL getName()
641 throw ( RuntimeException )
643 return ::rtl::OUString::createFromAscii( "Root" );
646 virtual Sequence< Reference< browse::XBrowseNode > > SAL_CALL
647 getChildNodes()
648 throw ( RuntimeException )
651 Sequence < Reference < browse::XBrowseNode > > locnBNs = getAllBrowseNodes( m_xComponentContext );
653 Sequence< Reference< browse::XBrowseNode > > children(
654 locnBNs.getLength() );
656 for ( sal_Int32 j = 0; j < locnBNs.getLength(); j++ )
658 children[j] = new LocationBrowseNode( locnBNs[j] );
661 return children;
664 virtual sal_Bool SAL_CALL hasChildNodes()
665 throw ( RuntimeException )
667 return sal_True; // will always be user and share
670 virtual sal_Int16 SAL_CALL getType()
671 throw ( RuntimeException )
673 return browse::BrowseNodeTypes::CONTAINER;
677 BrowseNodeFactoryImpl::BrowseNodeFactoryImpl(
678 Reference< XComponentContext > const & xComponentContext )
679 : m_xComponentContext( xComponentContext )
683 BrowseNodeFactoryImpl::~BrowseNodeFactoryImpl()
688 //############################################################################
689 // Implementation of XBrowseNodeFactory
690 //############################################################################
693 * The selector hierarchy is the standard hierarchy for organizers with the
694 * language nodes removed.
696 Reference< browse::XBrowseNode > SAL_CALL
697 BrowseNodeFactoryImpl::createView( sal_Int16 viewType )
698 throw (RuntimeException)
700 switch( viewType )
702 case browse::BrowseNodeFactoryViewTypes::MACROSELECTOR:
703 return getSelectorHierarchy();
704 case browse::BrowseNodeFactoryViewTypes::MACROORGANIZER:
705 return getOrganizerHierarchy();
706 default:
707 throw RuntimeException( OUSTR("Unknown view type" ), Reference< XInterface >() );
711 Reference< browse::XBrowseNode >
712 BrowseNodeFactoryImpl::getSelectorHierarchy()
713 throw (RuntimeException)
715 /*if ( !m_xSelectorBrowseNode.is() )
717 m_xSelectorBrowseNode = new SelectorBrowseNode( m_xComponentContext );
719 return new SelectorBrowseNode( m_xComponentContext );
722 Reference< browse::XBrowseNode >
723 BrowseNodeFactoryImpl::getOrganizerHierarchy()
724 throw (RuntimeException)
726 Reference< browse::XBrowseNode > xRet = new DefaultRootBrowseNode( m_xComponentContext );
727 return xRet;
729 //############################################################################
730 // Helper methods
731 //############################################################################
733 //############################################################################
734 // Namespace global methods for setting up BrowseNodeFactory service
735 //############################################################################
737 Sequence< ::rtl::OUString > SAL_CALL
738 bnf_getSupportedServiceNames( )
739 SAL_THROW( () )
741 ::rtl::OUString str_name = ::rtl::OUString::createFromAscii(
742 "com.sun.star.script.browse.BrowseNodeFactory");
744 return Sequence< ::rtl::OUString >( &str_name, 1 );
747 ::rtl::OUString SAL_CALL
748 bnf_getImplementationName( )
749 SAL_THROW( () )
751 return ::rtl::OUString::createFromAscii(
752 "com.sun.star.script.browse.BrowseNodeFactory" );
755 Reference< XInterface > SAL_CALL
756 bnf_create( Reference< XComponentContext > const & xComponentContext )
757 SAL_THROW( (Exception) )
759 return static_cast< ::cppu::OWeakObject * >(
760 new BrowseNodeFactoryImpl( xComponentContext ) );
763 //############################################################################
764 // Implementation of XServiceInfo
765 //############################################################################
767 ::rtl::OUString SAL_CALL
768 BrowseNodeFactoryImpl::getImplementationName()
769 throw (RuntimeException)
771 return bnf_getImplementationName();
774 Sequence< ::rtl::OUString > SAL_CALL
775 BrowseNodeFactoryImpl::getSupportedServiceNames()
776 throw (RuntimeException)
778 return bnf_getSupportedServiceNames();
781 sal_Bool BrowseNodeFactoryImpl::supportsService(
782 ::rtl::OUString const & serviceName )
783 throw (RuntimeException)
785 // check();
787 Sequence< ::rtl::OUString > supported_services(
788 getSupportedServiceNames() );
790 ::rtl::OUString const * ar = supported_services.getConstArray();
792 for ( sal_Int32 pos = supported_services.getLength(); pos--; )
794 if (ar[ pos ].equals( serviceName ))
795 return sal_True;
797 return sal_False;
800 } // namespace browsenodefactory