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