xref: /trunk/main/scripting/source/provider/MasterScriptProvider.cxx (revision b81185736b1dc1d0d31d3c6399b1242bd42a93a5)
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 <comphelper/documentinfo.hxx>
28 
29 #include <cppuhelper/implementationentry.hxx>
30 #include <cppuhelper/exc_hlp.hxx>
31 #include <cppuhelper/factory.hxx>
32 #include <tools/diagnose_ex.h>
33 
34 #include <com/sun/star/frame/XModel.hpp>
35 #include <com/sun/star/lang/EventObject.hpp>
36 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
37 #include <com/sun/star/document/XScriptInvocationContext.hpp>
38 
39 #include <com/sun/star/uri/XUriReference.hpp>
40 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
41 #include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
42 
43 #include <com/sun/star/deployment/XPackage.hpp>
44 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
45 #include <com/sun/star/script/provider/XScriptProviderFactory.hpp>
46 #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
47 
48 #include <util/scriptingconstants.hxx>
49 #include <util/util.hxx>
50 #include <util/MiscUtils.hxx>
51 
52 #include "ActiveMSPList.hxx"
53 #include "MasterScriptProvider.hxx"
54 #include "URIHelper.hxx"
55 
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::script;
59 using namespace ::com::sun::star::document;
60 using namespace ::sf_misc;
61 
62 namespace func_provider
63 {
64 //*************************************************************************
65 //  Definitions for MasterScriptProviderFactory global methods.
66 //*************************************************************************
67 
68 ::rtl::OUString SAL_CALL mspf_getImplementationName() ;
69 Reference< XInterface > SAL_CALL mspf_create( Reference< XComponentContext > const & xComponentContext );
70 Sequence< ::rtl::OUString > SAL_CALL mspf_getSupportedServiceNames();
71 
72 
73 bool endsWith( const ::rtl::OUString& target,
74     const ::rtl::OUString& item )
75 {
76     sal_Int32 index = 0;
77     if (  ( index = target.indexOf( item ) ) != -1  &&
78        ( index == ( target.getLength() - item.getLength() ) ) )
79     {
80         return true;
81     }
82     return false;
83 }
84 //::rtl_StandardModuleCount s_moduleCount = MODULE_COUNT_INIT;
85 
86 /* should be available in some central location. */
87 //*************************************************************************
88 // XScriptProvider implementation
89 //
90 //*************************************************************************
91 MasterScriptProvider::MasterScriptProvider( const Reference< XComponentContext > & xContext ):
92         m_xContext( xContext ), m_bIsValid( false ), m_bInitialised( false ),
93         m_bIsPkgMSP( false ), m_pPCache( 0 )
94 {
95     ENSURE_OR_THROW( m_xContext.is(), "MasterScriptProvider::MasterScriptProvider: No context available\n" );
96     m_xMgr = m_xContext->getServiceManager();
97     ENSURE_OR_THROW( m_xMgr.is(), "MasterScriptProvider::MasterScriptProvider: No service manager available\n" );
98     m_bIsValid = true;
99 }
100 
101 //*************************************************************************
102 MasterScriptProvider::~MasterScriptProvider()
103 {
104     //s_moduleCount.modCnt.release( &s_moduleCount.modCnt );
105     if ( m_pPCache )
106     {
107         delete m_pPCache;
108     }
109     m_pPCache = 0;
110 }
111 
112 //*************************************************************************
113 void SAL_CALL MasterScriptProvider::initialize( const Sequence < Any >& args )
114 {
115     if ( m_bInitialised )
116         return;
117 
118     m_bIsValid = false;
119 
120     sal_Int32 len = args.getLength();
121     if ( len > 1  )
122     {
123         throw RuntimeException(
124             OUSTR( "MasterScriptProvider::initialize: invalid number of arguments" ),
125             Reference< XInterface >() );
126     }
127 
128     Sequence< Any > invokeArgs( len );
129 
130     if ( len != 0 )
131     {
132         // check if first parameter is a string
133         // if it is, this implies that this is a MSP created
134         // with a user or share ctx ( used for browse functionality )
135         //
136         if ( args[ 0 ] >>= m_sCtxString )
137         {
138             invokeArgs[ 0  ] = args[ 0 ];
139             if ( m_sCtxString.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.tdoc" ) ) == 0 )
140             {
141                 m_xModel =  MiscUtils::tDocUrlToModel( m_sCtxString );
142             }
143         }
144         else if ( args[ 0 ] >>= m_xInvocationContext )
145         {
146             m_xModel.set( m_xInvocationContext->getScriptContainer(), UNO_QUERY_THROW );
147         }
148         else
149         {
150             args[ 0 ] >>= m_xModel;
151         }
152 
153         if ( m_xModel.is() )
154         {
155             // from the arguments, we were able to deduce a model. That alone doesn't
156             // suffice, we also need an XEmbeddedScripts which actually indicates support
157             // for embedding scripts
158             Reference< XEmbeddedScripts > xScripts( m_xModel, UNO_QUERY );
159             if ( !xScripts.is() )
160             {
161                 throw lang::IllegalArgumentException(
162                     ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
163                         "The given document does not support embedding scripts into it, and cannot be associated with such a document."
164                     ) ),
165                     *this,
166                     1
167                 );
168             }
169 
170             try
171             {
172                 m_sCtxString =  MiscUtils::xModelToTdocUrl( m_xModel, m_xContext );
173             }
174             catch ( const Exception& )
175             {
176                 Any aError( ::cppu::getCaughtException() );
177 
178                 ::rtl::OUStringBuffer buf;
179                 buf.appendAscii( "MasterScriptProvider::initialize: caught " );
180                 buf.append     ( aError.getValueTypeName() );
181                 buf.appendAscii( ":" );
182 
183                 Exception aException; aError >>= aException;
184                 buf.append     ( aException.Message );
185                 throw lang::WrappedTargetException( buf.makeStringAndClear(), *this, aError );
186             }
187 
188             if ( m_xInvocationContext.is() && m_xInvocationContext != m_xModel )
189                 invokeArgs[ 0 ] <<= m_xInvocationContext;
190             else
191                 invokeArgs[ 0 ] <<= m_sCtxString;
192         }
193 
194         ::rtl::OUString pkgSpec = OUSTR("uno_packages");
195         sal_Int32 indexOfPkgSpec = m_sCtxString.lastIndexOf( pkgSpec );
196 
197         // if context string ends with "uno_packages"
198         if ( indexOfPkgSpec > -1 && ( m_sCtxString.match( pkgSpec, indexOfPkgSpec ) == sal_True ) )
199         {
200             m_bIsPkgMSP = sal_True;
201         }
202         else
203         {
204             m_bIsPkgMSP = sal_False;
205         }
206     }
207     else // no args
208     {
209         // use either scripting context or maybe zero args?
210         invokeArgs = Sequence< Any >( 0 ); // no arguments
211     }
212     m_sAargs = invokeArgs;
213     // don't create pkg mgr MSP for documents, not supported
214     if ( m_bIsPkgMSP == sal_False && !m_xModel.is() )
215     {
216         createPkgProvider();
217     }
218 
219     m_bInitialised = true;
220     m_bIsValid = true;
221 }
222 
223 
224 //*************************************************************************
225 void MasterScriptProvider::createPkgProvider()
226 {
227     try
228     {
229         ::rtl::OUString loc = m_sCtxString;
230         Any location;
231         ::rtl::OUString sPkgCtx =  m_sCtxString.concat( OUSTR(":uno_packages") );
232         location <<= sPkgCtx;
233 
234         Reference< provider::XScriptProviderFactory > xFac(
235             m_xContext->getValueByName(
236                 OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY_THROW );
237 
238         m_xMSPPkg.set(
239             xFac->createScriptProvider( location ), UNO_QUERY_THROW );
240 
241     }
242     catch ( Exception& e )
243     {
244         (void)e;
245         OSL_TRACE("Exception creating MasterScriptProvider for uno_packages in context %s: %s",
246                 ::rtl::OUStringToOString( m_sCtxString,
247                     RTL_TEXTENCODING_ASCII_US ).pData->buffer,
248                 ::rtl::OUStringToOString( e.Message,
249                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
250     }
251 }
252 
253 //*************************************************************************
254 Reference< provider::XScript >
255 MasterScriptProvider::getScript( const ::rtl::OUString& scriptURI )
256 {
257     if ( !isValid() )
258     {
259         throw provider::ScriptFrameworkErrorException(
260             OUSTR( "MasterScriptProvider not initialised" ), Reference< XInterface >(),
261             scriptURI, OUSTR(""),
262             provider::ScriptFrameworkErrorType::UNKNOWN );
263     }
264 
265     // need to get the language from the string
266 
267     Reference< uri::XUriReferenceFactory > xFac (
268          m_xMgr->createInstanceWithContext( rtl::OUString::createFromAscii(
269             "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY );
270     if ( !xFac.is() )
271     {
272         ::rtl::OUString message = ::rtl::OUString::createFromAscii("Failed to instantiate  UriReferenceFactory");
273         throw provider::ScriptFrameworkErrorException(
274             message, Reference< XInterface >(),
275             scriptURI, ::rtl::OUString(),
276             provider::ScriptFrameworkErrorType::UNKNOWN );
277     }
278 
279     Reference<  uri::XUriReference > uriRef(
280         xFac->parse( scriptURI ), UNO_QUERY );
281 
282     Reference < uri::XVndSunStarScriptUrl > sfUri( uriRef, UNO_QUERY );
283 
284     if ( !uriRef.is() || !sfUri.is() )
285     {
286         ::rtl::OUString errorMsg = OUSTR( "Incorrect format for Script URI: " );
287         errorMsg = errorMsg.concat( scriptURI );
288         throw provider::ScriptFrameworkErrorException(
289             errorMsg, Reference< XInterface >(),
290             scriptURI, OUSTR(""),
291             provider::ScriptFrameworkErrorType::UNKNOWN );
292     }
293 
294     ::rtl::OUString langKey = ::rtl::OUString::createFromAscii( "language" );
295     ::rtl::OUString locKey = ::rtl::OUString::createFromAscii( "location" );
296 
297     if ( sfUri->hasParameter( langKey ) == sal_False ||
298          sfUri->hasParameter( locKey ) == sal_False ||
299          ( sfUri->getName().getLength() == 0  ) )
300     {
301         ::rtl::OUString errorMsg = OUSTR( "Incorrect format for Script URI: " );
302         errorMsg = errorMsg.concat( scriptURI );
303         throw provider::ScriptFrameworkErrorException(
304             errorMsg, Reference< XInterface >(),
305             scriptURI, OUSTR(""),
306             provider::ScriptFrameworkErrorType::UNKNOWN );
307     }
308 
309     ::rtl::OUString language = sfUri->getParameter( langKey );
310     ::rtl::OUString location = sfUri->getParameter( locKey );
311 
312     // if script us located in uno pkg
313     sal_Int32 index = -1;
314     ::rtl::OUString pkgTag =
315         ::rtl::OUString::createFromAscii( ":uno_packages" );
316     // for languages other than basic,  scripts located in uno packages
317     // are merged into the user/share location context.
318     // For other languages the location attribute in script url has the form
319     // location = [user|share]:uno_packages or location :uno_packages/xxxx.uno.pkg
320     // we need to extract the value of location part from the
321     // location attribute of the script, if the script is located in an
322     // uno package then that is the location part up to and including
323     // ":uno_packages", if the script is not in an uno package then the
324     // normal value is used e.g. user or share.
325     // The value extracted will be used to determine if the script is
326     // located in the same location context as this MSP.
327     // For Basic, the language script provider can handle the execution of a
328     // script in any location context
329     if ( ( index = location.indexOf( pkgTag ) ) > -1 )
330     {
331         location = location.copy( 0, index + pkgTag.getLength() );
332     }
333 
334     Reference< provider::XScript > xScript;
335 
336     // If the script location is in the same location context as this
337     // MSP then delegate to the language provider controlled by this MSP
338     // ** Special case is BASIC, all calls to getScript will be handled
339     // by the language script provider in the current location context
340     // even if its different
341     if  (   (   location.equals( OUSTR( "document" ) )
342             &&  m_xModel.is()
343             )
344             ||  ( endsWith( m_sCtxString, location ) )
345             ||  ( language.equals( OUSTR( "Basic" ) ) )
346          )
347     {
348         Reference< provider::XScriptProvider > xScriptProvider;
349         ::rtl::OUStringBuffer buf( 80 );
350         buf.appendAscii( "com.sun.star.script.provider.ScriptProviderFor");
351         buf.append( language );
352         ::rtl::OUString serviceName = buf.makeStringAndClear();
353         if ( providerCache() )
354         {
355             try
356             {
357                 xScriptProvider.set(
358                     providerCache()->getProvider( serviceName ),
359                     UNO_QUERY_THROW );
360             }
361             catch( const Exception& e )
362             {
363                 throw provider::ScriptFrameworkErrorException(
364                     e.Message, Reference< XInterface >(),
365                     sfUri->getName(), language,
366                     provider::ScriptFrameworkErrorType::NOTSUPPORTED );
367             }
368         }
369         else
370         {
371             throw provider::ScriptFrameworkErrorException(
372                 OUSTR( "No LanguageProviders detected" ),
373                 Reference< XInterface >(),
374                 sfUri->getName(), language,
375                 provider::ScriptFrameworkErrorType::NOTSUPPORTED );
376         }
377         xScript=xScriptProvider->getScript( scriptURI );
378     }
379     else
380     {
381         Reference< provider::XScriptProviderFactory > xFac_(
382             m_xContext->getValueByName(
383                 OUSTR( "/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") ), UNO_QUERY_THROW );
384 
385         Reference< provider::XScriptProvider > xSP(
386             xFac_->createScriptProvider( makeAny( location ) ), UNO_QUERY_THROW );
387         xScript = xSP->getScript( scriptURI );
388     }
389 
390     return xScript;
391 }
392 //*************************************************************************
393 bool
394 MasterScriptProvider::isValid()
395 {
396     return m_bIsValid;
397 }
398 
399 //*************************************************************************
400 ProviderCache*
401 MasterScriptProvider::providerCache()
402 {
403     if ( !m_pPCache )
404     {
405         ::osl::MutexGuard aGuard( m_mutex );
406         if ( !m_pPCache )
407         {
408             ::rtl::OUString serviceName1 = OUSTR("com.sun.star.script.provider.ScriptProviderForBasic");
409             Sequence< ::rtl::OUString > blacklist(1);
410             blacklist[ 0 ] = serviceName1;
411 
412             if ( !m_bIsPkgMSP )
413             {
414                 m_pPCache = new ProviderCache( m_xContext, m_sAargs );
415             }
416             else
417             {
418                 m_pPCache = new ProviderCache( m_xContext, m_sAargs, blacklist );
419             }
420         }
421     }
422     return m_pPCache;
423 }
424 
425 
426 //*************************************************************************
427 ::rtl::OUString SAL_CALL
428 MasterScriptProvider::getName()
429 {
430     if ( !isPkgProvider() )
431     {
432         ::rtl::OUString sCtx = getContextString();
433         if ( sCtx.indexOf( OUSTR( "vnd.sun.star.tdoc" ) ) == 0 )
434         {
435             Reference< frame::XModel > xModel = m_xModel;
436             if ( !xModel.is() )
437             {
438                 xModel = MiscUtils::tDocUrlToModel( sCtx );
439             }
440 
441             m_sNodeName = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
442         }
443         else
444         {
445             m_sNodeName = parseLocationName( getContextString() );
446         }
447     }
448     else
449     {
450         m_sNodeName = OUSTR("uno_packages");
451     }
452     return m_sNodeName;
453 }
454 
455 //*************************************************************************
456 Sequence< Reference< browse::XBrowseNode > > SAL_CALL
457 MasterScriptProvider::getChildNodes()
458 {
459     Sequence< Reference< provider::XScriptProvider > > providers = getAllProviders();
460 
461     Reference< provider::XScriptProvider > pkgProv = getPkgProvider();
462     sal_Int32 size = providers.getLength();
463     bool hasPkgs = pkgProv.is();
464     if ( hasPkgs  )
465     {
466         size++;
467     }
468     Sequence<  Reference< browse::XBrowseNode > > children( size );
469     sal_Int32 provIndex = 0;
470     for ( ; provIndex < providers.getLength(); provIndex++ )
471     {
472         children[ provIndex ] = Reference< browse::XBrowseNode >( providers[ provIndex ], UNO_QUERY );
473     }
474 
475     if ( hasPkgs  )
476     {
477         children[ provIndex ] = Reference< browse::XBrowseNode >( pkgProv, UNO_QUERY );
478 
479     }
480 
481     return children;
482 }
483 
484 //*************************************************************************
485 sal_Bool SAL_CALL
486 MasterScriptProvider::hasChildNodes()
487 {
488     return sal_True;
489 }
490 
491 //*************************************************************************
492 sal_Int16 SAL_CALL
493 MasterScriptProvider::getType()
494 {
495     return browse::BrowseNodeTypes::CONTAINER;
496 }
497 
498 //*************************************************************************
499 
500 ::rtl::OUString
501 MasterScriptProvider::parseLocationName( const ::rtl::OUString& location )
502 {
503     // strip out the last leaf of location name
504     // e.g. file://dir1/dir2/Blah.sxw - > Blah.sxw
505     ::rtl::OUString temp = location;
506     INetURLObject aURLObj( temp );
507     if ( !aURLObj.HasError() )
508         temp = aURLObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
509     return temp;
510 }
511 
512 //*************************************************************************
513 // Register Package
514 void SAL_CALL
515 MasterScriptProvider::insertByName( const ::rtl::OUString& aName, const Any& aElement )
516 {
517     if ( !m_bIsPkgMSP )
518     {
519         if ( m_xMSPPkg.is() )
520         {
521             Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY );
522             if ( !xCont.is() )
523             {
524                 throw RuntimeException(
525                     OUSTR("PackageMasterScriptProvider doesn't implement XNameContainer"),
526                     Reference< XInterface >() );
527             }
528             xCont->insertByName( aName, aElement );
529         }
530         else
531         {
532             throw RuntimeException( OUSTR("PackageMasterScriptProvider is unitialised"),
533                                         Reference< XInterface >() );
534         }
535 
536     }
537     else
538     {
539         Reference< deployment::XPackage > xPkg( aElement, UNO_QUERY );
540         if ( !xPkg.is() )
541         {
542             throw lang::IllegalArgumentException( OUSTR("Couldn't convert to XPackage"),
543                                                       Reference < XInterface > (), 2 );
544         }
545         if ( !aName.getLength() )
546         {
547             throw lang::IllegalArgumentException( OUSTR("Name not set!!"),
548                                                       Reference < XInterface > (), 1 );
549         }
550         // TODO for library package parse the language, for the moment will try
551         // to get each provider to process the new Package, the first one the succeeds
552         // will terminate processing
553         if ( !providerCache() )
554         {
555             throw RuntimeException(
556                 OUSTR("insertByName cannot instantiate "
557                     "child script providers."),
558                 Reference< XInterface >() );
559         }
560         Sequence < Reference< provider::XScriptProvider > > xSProviders =
561             providerCache()->getAllProviders();
562         sal_Int32 index = 0;
563 
564         for ( ; index < xSProviders.getLength(); index++ )
565         {
566             Reference< container::XNameContainer > xCont( xSProviders[ index ], UNO_QUERY );
567             if ( !xCont.is() )
568             {
569                 continue;
570             }
571             try
572             {
573                 xCont->insertByName( aName, aElement );
574                 break;
575             }
576             catch ( Exception& )
577             {
578             }
579 
580         }
581         if ( index == xSProviders.getLength() )
582         {
583             // No script providers could process the package
584             ::rtl::OUString message = OUSTR("Failed to register package for ");
585             message = message.concat( aName );
586             throw lang::IllegalArgumentException( message,
587                 Reference < XInterface > (), 2 );
588         }
589    }
590 }
591 
592 //*************************************************************************
593 // Revoke Package
594 void SAL_CALL
595 MasterScriptProvider::removeByName( const ::rtl::OUString& Name )
596 {
597     if ( !m_bIsPkgMSP )
598     {
599         if ( m_xMSPPkg.is() )
600         {
601             Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY );
602             if ( !xCont.is() )
603             {
604                 throw RuntimeException(
605                     OUSTR("PackageMasterScriptProvider doesn't implement XNameContainer"),
606                     Reference< XInterface >() );
607             }
608             xCont->removeByName( Name );
609         }
610         else
611         {
612             throw RuntimeException( OUSTR("PackageMasterScriptProvider is unitialised"),
613                                         Reference< XInterface >() );
614         }
615 
616    }
617    else
618    {
619         if ( !Name.getLength() )
620         {
621             throw lang::IllegalArgumentException( OUSTR("Name not set!!"),
622                                                       Reference < XInterface > (), 1 );
623         }
624         // TODO for Script library package url parse the language,
625         // for the moment will just try to get each provider to process remove/revoke
626         // request, the first one the succeeds will terminate processing
627 
628         if ( !providerCache() )
629         {
630             throw RuntimeException(
631                 OUSTR("removeByName() cannot instantiate "
632                     "child script providers."),
633                 Reference< XInterface >() );
634         }
635         Sequence < Reference< provider::XScriptProvider > > xSProviders =
636             providerCache()->getAllProviders();
637         sal_Int32 index = 0;
638         for ( ; index < xSProviders.getLength(); index++ )
639         {
640             Reference< container::XNameContainer > xCont( xSProviders[ index ], UNO_QUERY );
641             if ( !xCont.is() )
642             {
643                 continue;
644             }
645             try
646             {
647                 xCont->removeByName( Name );
648                 break;
649             }
650             catch ( Exception& )
651             {
652             }
653 
654         }
655         if ( index == xSProviders.getLength() )
656         {
657             // No script providers could process the package
658             ::rtl::OUString message = OUSTR("Failed to revoke package for ");
659             message = message.concat( Name );
660             throw lang::IllegalArgumentException( message,
661                                                       Reference < XInterface > (), 1 );
662         }
663 
664     }
665 }
666 
667 //*************************************************************************
668 void SAL_CALL
669 MasterScriptProvider::replaceByName( const ::rtl::OUString& aName, const Any& aElement )
670 {
671     (void)aName;
672     (void)aElement;
673 
674     // TODO needs implementing
675     if ( true )
676     {
677         throw RuntimeException(  OUSTR("replaceByName not implemented!!!!") ,
678                 Reference< XInterface >() );
679     }
680 }
681 //*************************************************************************
682 Any SAL_CALL
683 MasterScriptProvider::getByName( const ::rtl::OUString& aName )
684 {
685     (void)aName;
686 
687     // TODO needs to be implemented
688     Any result;
689     if ( true )
690     {
691         throw RuntimeException(  OUSTR("getByName not implemented!!!!") ,
692                 Reference< XInterface >() );
693     }
694     return result;
695 }
696 //*************************************************************************
697 sal_Bool SAL_CALL
698 MasterScriptProvider::hasByName( const ::rtl::OUString& aName )
699 {
700     sal_Bool result = sal_False;
701     if ( !m_bIsPkgMSP )
702     {
703         if ( m_xMSPPkg.is() )
704         {
705             Reference< container::XNameContainer > xCont( m_xMSPPkg, UNO_QUERY );
706             if ( !xCont.is() )
707             {
708                 throw RuntimeException(
709                     OUSTR("PackageMasterScriptProvider doesn't implement XNameContainer"),
710                     Reference< XInterface >() );
711             }
712 
713             result = xCont->hasByName( aName );
714         }
715         else
716         {
717             throw RuntimeException( OUSTR("PackageMasterScriptProvider is unitialised"),
718                                         Reference< XInterface >() );
719         }
720 
721    }
722    else
723    {
724         if ( !aName.getLength() )
725         {
726             throw lang::IllegalArgumentException( OUSTR("Name not set!!"),
727                                                       Reference < XInterface > (), 1 );
728         }
729         // TODO for Script library package url parse the language,
730         // for the moment will just try to get each provider to see if the
731         // package exists in any provider, first one that succeed will
732         // terminate the loop
733 
734         if ( !providerCache() )
735         {
736             throw RuntimeException(
737                 OUSTR("removeByName() cannot instantiate "
738                     "child script providers."),
739                 Reference< XInterface >() );
740         }
741         Sequence < Reference< provider::XScriptProvider > > xSProviders =
742             providerCache()->getAllProviders();
743         for ( sal_Int32 index = 0; index < xSProviders.getLength(); index++ )
744         {
745             Reference< container::XNameContainer > xCont( xSProviders[ index ], UNO_QUERY );
746             if ( !xCont.is() )
747             {
748                 continue;
749             }
750             try
751             {
752                 result = xCont->hasByName( aName );
753                 if ( result == sal_True )
754                 {
755                     break;
756                 }
757             }
758             catch ( Exception& )
759             {
760             }
761 
762         }
763     }
764     return result;
765 }
766 
767 //*************************************************************************
768 Sequence< ::rtl::OUString > SAL_CALL
769 MasterScriptProvider::getElementNames(  )
770 {
771     // TODO needs implementing
772     Sequence< ::rtl::OUString >  names;
773     if ( true )
774     {
775         throw RuntimeException(  OUSTR("getElementNames not implemented!!!!") ,
776                 Reference< XInterface >() );
777     }
778     return names;
779 }
780 //*************************************************************************
781 Type SAL_CALL
782 MasterScriptProvider::getElementType(  )
783 {
784     // TODO needs implementing
785     Type t;
786     return t;
787 }
788 //*************************************************************************
789 sal_Bool SAL_CALL MasterScriptProvider::hasElements(  )
790 {
791     // TODO needs implementing
792     if ( true )
793     {
794         throw RuntimeException(  OUSTR("hasElements not implemented!!!!") ,
795                 Reference< XInterface >() );
796     }
797     return false;
798 }
799 
800 //*************************************************************************
801 Sequence< Reference< provider::XScriptProvider > > SAL_CALL
802 MasterScriptProvider::getAllProviders()
803 {
804     if ( providerCache() )
805     {
806         return providerCache()->getAllProviders();
807     }
808     else
809     {
810         ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii(
811             "MasterScriptProvider::getAllProviders, cache not initialised");
812         throw RuntimeException( errorMsg.concat( errorMsg ),
813             Reference< XInterface >() );
814     }
815 }
816 
817 
818 //*************************************************************************
819 ::rtl::OUString SAL_CALL MasterScriptProvider::getImplementationName( )
820 {
821     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
822         "com.sun.star.script.provider.MasterScriptProvider" ) );
823 }
824 
825 //*************************************************************************
826 sal_Bool SAL_CALL MasterScriptProvider::supportsService( const ::rtl::OUString& serviceName )
827 {
828     Sequence< ::rtl::OUString > serviceNames( getSupportedServiceNames() );
829     ::rtl::OUString const * pNames = serviceNames.getConstArray();
830     for ( sal_Int32 nPos = serviceNames.getLength(); nPos--; )
831     {
832         if ( serviceName.equals( pNames[ nPos ] ) )
833         {
834             return sal_True;
835         }
836     }
837     return sal_False;
838 }
839 
840 //*************************************************************************
841 Sequence< ::rtl::OUString > SAL_CALL MasterScriptProvider::getSupportedServiceNames( )
842 {
843     ::rtl::OUString names[3];
844 
845     names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
846         "com.sun.star.script.provider.MasterScriptProvider" ) );
847     names[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
848         "com.sun.star.script.browse.BrowseNode" ) );
849     names[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
850         "com.sun.star.script.provider.ScriptProvider" ) );
851 
852     return Sequence< ::rtl::OUString >( names, 3 );
853 }
854 
855 } // namespace func_provider
856 
857 
858 namespace browsenodefactory
859 {
860 ::rtl::OUString SAL_CALL bnf_getImplementationName() ;
861 Reference< XInterface > SAL_CALL bnf_create( Reference< XComponentContext > const & xComponentContext );
862 Sequence< ::rtl::OUString > SAL_CALL bnf_getSupportedServiceNames();
863 }
864 
865 namespace scripting_runtimemgr
866 {
867 //*************************************************************************
868 Reference< XInterface > SAL_CALL sp_create(
869     const Reference< XComponentContext > & xCompC )
870 {
871     return ( cppu::OWeakObject * ) new ::func_provider::MasterScriptProvider( xCompC );
872 }
873 
874 //*************************************************************************
875 Sequence< ::rtl::OUString > sp_getSupportedServiceNames( )
876     SAL_THROW( () )
877 {
878     ::rtl::OUString names[3];
879 
880     names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
881         "com.sun.star.script.provider.MasterScriptProvider" ) );
882     names[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
883         "com.sun.star.script.browse.BrowseNode" ) );
884     names[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
885         "com.sun.star.script.provider.ScriptProvider" ) );
886 
887     return Sequence< ::rtl::OUString >( names, 3 );
888 }
889 
890 //*************************************************************************
891 ::rtl::OUString sp_getImplementationName( )
892 SAL_THROW( () )
893 {
894     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM (
895         "com.sun.star.script.provider.MasterScriptProvider" ) );
896 }
897 
898 // ***** registration or ScriptingFrameworkURIHelper
899 Reference< XInterface > SAL_CALL urihelper_create(
900     const Reference< XComponentContext > & xCompC )
901 {
902     return ( cppu::OWeakObject * )
903         new ::func_provider::ScriptingFrameworkURIHelper( xCompC );
904 }
905 
906 Sequence< ::rtl::OUString > urihelper_getSupportedServiceNames( )
907     SAL_THROW( () )
908 {
909     ::rtl::OUString serviceNameList[] = {
910         ::rtl::OUString::createFromAscii(
911             "com.sun.star.script.provider.ScriptURIHelper" ) };
912 
913     Sequence< ::rtl::OUString > serviceNames = Sequence <
914         ::rtl::OUString > ( serviceNameList, 1 );
915 
916     return serviceNames;
917 }
918 
919 ::rtl::OUString urihelper_getImplementationName( )
920     SAL_THROW( () )
921 {
922     return ::rtl::OUString::createFromAscii(
923         "com.sun.star.script.provider.ScriptURIHelper");
924 }
925 
926 static struct cppu::ImplementationEntry s_entries [] =
927     {
928         {
929             sp_create, sp_getImplementationName,
930             sp_getSupportedServiceNames, cppu::createSingleComponentFactory,
931             0, 0
932         },
933         {
934             urihelper_create,
935             urihelper_getImplementationName,
936             urihelper_getSupportedServiceNames,
937             cppu::createSingleComponentFactory,
938             0, 0
939         },
940         {
941             func_provider::mspf_create, func_provider::mspf_getImplementationName,
942             func_provider::mspf_getSupportedServiceNames, cppu::createSingleComponentFactory,
943             0, 0
944         },
945         {
946             browsenodefactory::bnf_create, browsenodefactory::bnf_getImplementationName,
947             browsenodefactory::bnf_getSupportedServiceNames, cppu::createSingleComponentFactory,
948             0, 0
949         },
950         { 0, 0, 0, 0, 0, 0 }
951     };
952 }
953 
954 //############################################################################
955 //#### EXPORTED ##############################################################
956 //############################################################################
957 
958 /**
959  * Gives the environment this component belongs to.
960  */
961 extern "C"
962 {
963     SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment(
964             const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
965     {
966         (void)ppEnv;
967         *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
968     }
969 
970     /**
971      * This function is called to get service factories for an implementation.
972      *
973      * @param pImplName       name of implementation
974      * @param pServiceManager a service manager, need for component creation
975      * @param pRegistryKey    the registry key for this component, need for persistent
976      *                        data
977      * @return a component factory
978      */
979     SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(
980         const sal_Char * pImplName,
981         lang::XMultiServiceFactory * pServiceManager,
982         registry::XRegistryKey * pRegistryKey )
983     {
984         return ::cppu::component_getFactoryHelper( pImplName, pServiceManager,
985             pRegistryKey, ::scripting_runtimemgr::s_entries );
986     }
987 }
988