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