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 <vector>
28 #include <stdlib.h>
29 
30 #include <cppuhelper/implementationentry.hxx>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/security/AccessControlException.hpp>
33 
34 #include <util/util.hxx>
35 #include <util/scriptingconstants.hxx>
36 
37 #include <drafts/com/sun/star/script/framework/storage/XScriptStorageManager.hpp>
38 #include <drafts/com/sun/star/script/framework/security/XScriptSecurity.hpp>
39 
40 #include "ScriptNameResolverImpl.hxx"
41 #include "ScriptRuntimeManager.hxx"
42 
43 using namespace ::rtl;
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::drafts::com::sun::star::script::framework;
47 
48 namespace scripting_runtimemgr
49 {
50 
51 const sal_Char* const LANGUAGE_TO_RESOLVE_ON[] = { "All" }; // should be configurable
52 OUString nrs_implName = OUString::createFromAscii(
53     "drafts.com.sun.star.script.framework.runtime.DefaultScriptNameResolver" );
54 OUString nrs_serviceName = OUString::createFromAscii(
55     "drafts.com.sun.star.script.framework.runtime.DefaultScriptNameResolver" );
56 Sequence< OUString > nrs_serviceNames = Sequence< OUString >( &nrs_serviceName, 1 );
57 
58 const char* const SCRIPTSTORAGEMANAGER_SERVICE =
59     "/singletons/drafts.com.sun.star.script.framework.storage.theScriptStorageManager";
60 
61 extern ::rtl_StandardModuleCount s_moduleCount;
62 
63 // define storages to search
64 static ::std::vector< sal_Int32 >* m_pSearchIDs = NULL;
65 
66 //*************************************************************************
ScriptNameResolverImpl(const Reference<XComponentContext> & xContext)67 ScriptNameResolverImpl::ScriptNameResolverImpl(
68     const Reference< XComponentContext > & xContext ) :
69     m_xContext( xContext, UNO_SET_THROW )
70 {
71     OSL_TRACE( "< ScriptNameResolverImpl ctor called >\n" );
72     validateXRef( m_xContext, "ScriptNameResolverImpl::ScriptNameResolverImpl: invalid context" );
73     m_xMultiComFac.set( m_xContext->getServiceManager(), UNO_SET_THROW );
74 
75     if( !m_pSearchIDs )
76     {
77         osl::Guard< osl::Mutex > aGuard( m_mutex );
78         if( !m_pSearchIDs )
79         {
80             scripting_constants::ScriptingConstantsPool& scriptingConstantsPool =
81                 scripting_constants::ScriptingConstantsPool::instance();
82             m_pSearchIDs = new ::std::vector< sal_Int32 >();
83             m_pSearchIDs->push_back( scriptingConstantsPool.DOC_STORAGE_ID_NOT_SET );
84             m_pSearchIDs->push_back( scriptingConstantsPool.USER_STORAGE_ID );
85             m_pSearchIDs->push_back( scriptingConstantsPool.SHARED_STORAGE_ID );
86         }
87     }
88 
89     s_moduleCount.modCnt.acquire( &s_moduleCount.modCnt );
90 }
91 
92 //*************************************************************************
~ScriptNameResolverImpl()93 ScriptNameResolverImpl::~ScriptNameResolverImpl()
94 {
95     OSL_TRACE( "< ScriptNameResolverImpl dtor called >\n" );
96     s_moduleCount.modCnt.release( &s_moduleCount.modCnt );
97 }
98 
99 //*************************************************************************
resolve(const::rtl::OUString & scriptURI,Any & invocationCtx)100 Reference< storage::XScriptInfo > ScriptNameResolverImpl::resolve(
101 const ::rtl::OUString & scriptURI, Any& invocationCtx )
102 throw ( lang::IllegalArgumentException, script::CannotConvertException, RuntimeException )
103 {
104 
105     Reference< storage::XScriptInfo > resolvedName;
106     Reference< beans::XPropertySet > xPropSetScriptingContext;
107     scripting_constants::ScriptingConstantsPool& scriptingConstantsPool =
108             scripting_constants::ScriptingConstantsPool::instance();
109 
110     OSL_TRACE( "ScriptNameResolverImpl::resolve: in resolve - start" );
111 
112     if ( sal_False == ( invocationCtx >>= xPropSetScriptingContext ) )
113     {
114         throw RuntimeException( OUSTR(
115             "ScriptNameResolverImpl::resolve : unable to get XScriptingContext from param" ),
116             Reference< XInterface > () );
117     }
118 
119     Any any;
120     OUString docUri;
121     sal_Int32 filesysScriptStorageID = -1;
122     Reference < storage::XScriptStorageManager > xScriptStorageMgr;
123     sal_Int32 docSid;
124     try
125     {
126         any = xPropSetScriptingContext->getPropertyValue(
127             scriptingConstantsPool.DOC_URI );
128         OSL_TRACE( "ScriptNameResolverImpl::resolve: in resolve - got anyUri" );
129         if ( sal_False == ( any >>= docUri ) )
130         {
131             throw RuntimeException( OUSTR(
132             "ScriptNameResolverImpl::resolve : unable to get doc Uri from xPropSetScriptingContext" ),
133                 Reference< XInterface > () );
134         }
135         any = xPropSetScriptingContext->getPropertyValue(
136             scriptingConstantsPool.DOC_STORAGE_ID );
137         if ( sal_False == ( any >>= docSid ) )
138         {
139             throw RuntimeException( OUSTR(
140                 "ScriptNameResolverImpl::resolve : unable to get doc storage id from xPropSetScriptingContext" ),
141                 Reference< XInterface > () );
142         }
143     }
144     catch ( Exception & e )
145     {
146         OUString temp = OUSTR(
147             "ScriptNameResolverImpl::resolve : problem with getPropertyValue" );
148         throw RuntimeException( temp.concat( e.Message ),
149                                 Reference< XInterface > () );
150     }
151 #ifdef _DEBUG
152     catch ( ... )
153     {
154         throw RuntimeException( OUSTR(
155             "ScriptNameResolverImpl::resolve Unknown Exception caught - RuntimeException rethrown" ),
156             Reference< XInterface > () );
157     }
158 #endif
159 
160 
161     ::rtl::OString docUriO(
162         ::rtl::OUStringToOString( docUri , RTL_TEXTENCODING_ASCII_US ) );
163     OSL_TRACE(
164         "ScriptNameResolverImpl::resolve: *** >>> DOC URI: %s, doc sid is %d\n",
165         docUriO.pData->buffer, docSid );
166 
167 
168     OSL_TRACE( "ScriptNameResolverImpl::resolve Starting..." );
169     OUString docString = OUString::createFromAscii( "location=document" );
170     OUString userString = OUString::createFromAscii( "location=user" );
171     OUString shareString = OUString::createFromAscii( "location=share" );
172     OUString filesysString = OUString::createFromAscii( "location=filesystem" );
173 
174     // initialise vector with doc, user and share
175 
176     // m_pSearchIDs is initialised as follows,
177     // m_pSearchIDs [ 0 ] empty
178     // m_pSearchIDs [ 1 ] user storage id
179     // m_pSearchIDs [ 2 ] share "      "
180 
181     ::std::vector< sal_Int32 > m_vSearchIDs = *m_pSearchIDs;
182     m_vSearchIDs[ 0 ] = docSid;
183 
184     if ( scriptURI.indexOf( docString ) != -1 )
185     {
186         OSL_TRACE("Full resolution available, search document");
187         // search in document
188         m_vSearchIDs.resize( 1 );
189     }
190     else if ( scriptURI.indexOf( userString ) != -1 )
191     {
192         OSL_TRACE("Full resolution available, search user");
193         // search in user
194         m_vSearchIDs[ 0 ] = ( *m_pSearchIDs )[ 1 ];
195         m_vSearchIDs.resize( 1 );
196     }
197     else if ( scriptURI.indexOf( shareString ) != -1 )
198     {
199         OSL_TRACE("Full resolution available, search share");
200         // search in share
201         m_vSearchIDs[ 0 ] = ( *m_pSearchIDs )[ 2 ];
202         m_vSearchIDs.resize( 1 );
203     }
204     else if ( scriptURI.indexOf( filesysString ) != -1 )
205     {
206         OSL_TRACE("Full resolution available, create & search filesystem");
207         OUString filesysURL;
208         try
209         {
210             filesysURL = getFilesysURL( scriptURI );
211         }
212         catch ( lang::IllegalArgumentException & e )
213         {
214             OUString temp = OUSTR( "ScriptNameResolverImpl::resolve: " );
215             throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() );
216         }
217         Reference< XInterface > xInterface(
218             m_xMultiComFac->createInstanceWithContext(
219                 ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
220                 m_xContext
221             ),
222             UNO_SET_THROW
223         );
224         Reference < ucb::XSimpleFileAccess > xSimpleFileAccess = Reference <
225                     ucb::XSimpleFileAccess > ( xInterface, UNO_QUERY_THROW );
226 
227         // do we need to encode this? hope not.
228         OSL_TRACE( ">>>> About to create storage for %s",
229                 ::rtl::OUStringToOString( filesysURL,
230                     RTL_TEXTENCODING_ASCII_US ).pData->buffer );
231         // ask storage manager to create storage
232         try
233         {
234             // need to get the ScriptStorageManager
235             xScriptStorageMgr.set( m_xContext->getValueByName(
236                     scriptingConstantsPool.SCRIPTSTORAGEMANAGER_SERVICE ), UNO_QUERY_THROW );
237             filesysScriptStorageID =
238                     xScriptStorageMgr->createScriptStorageWithURI(
239                         xSimpleFileAccess, filesysURL );
240                 OSL_TRACE( ">>>> Created storage %d - for %s ",
241                     filesysScriptStorageID, ::rtl::OUStringToOString(
242                         filesysURL, RTL_TEXTENCODING_ASCII_US ).pData->buffer );
243         }
244         catch ( RuntimeException & e )
245         {
246             OUString temp = OUSTR( "ScriptNameResolverImpl::resolve: " );
247             throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() );
248         }
249         m_vSearchIDs[ 0 ] = filesysScriptStorageID;
250         m_vSearchIDs.resize( 1 );
251     }
252     else
253     {
254         OSL_TRACE("Only partial uri available, search doc, user & share");
255         // is this illegal or do we search in a default way
256         // if we get to here a uri has been passed in that has:
257         // a) not got a location specified
258         // b) an illegal location
259 
260         // detect illegal location
261         if (  scriptURI.indexOf( OUString::createFromAscii( "location=" ) ) != -1 )
262         {
263             OSL_TRACE(
264                 "ScriptNameResolver::resolve, throwing IllegalArgException" );
265             throw lang::IllegalArgumentException(
266                 OUSTR( "invalid URI: " ).concat( scriptURI ),
267                 Reference < XInterface > (), 1 );
268 
269         }
270         // leave vSearchIDs take care of the search...
271     }
272 
273     ::std::vector< sal_Int32 >::const_iterator iter;
274     ::std::vector< sal_Int32 >::const_iterator iterEnd = m_vSearchIDs.end();
275 
276     for ( iter = m_vSearchIDs.begin() ; iter != iterEnd; ++iter )
277     {
278         try
279         {
280             OSL_TRACE( "** about to resolve from storage using id %d from vector of size %d",
281                 *iter, m_vSearchIDs.size() );
282             if ( ( resolvedName = resolveURIFromStorageID( *iter, docUri, scriptURI ) ).is() )
283             {
284                 OSL_TRACE( "found match in uri from storage %d", *iter );
285                 xPropSetScriptingContext->setPropertyValue(
286                 scriptingConstantsPool.RESOLVED_STORAGE_ID, makeAny(*iter) );
287                 break;
288             }
289 
290         }
291         catch ( css::security::AccessControlException  & e )
292         {
293             // no execute permission
294             OSL_TRACE( "ScriptNameResolverImpl::resolve : AccessControlException " );
295             continue;
296         }
297         catch ( beans::UnknownPropertyException & e )
298         {
299             OUString temp = OUSTR(
300                 "ScriptNameResolverImpl::resolve : UnknownPropertyException" );
301             throw RuntimeException( temp.concat( e.Message ),
302                 Reference< XInterface > () );
303         }
304         catch ( beans::PropertyVetoException  & e )
305         {
306             OUString temp = OUSTR(
307                 "ScriptNameResolverImpl::resolve : PropertyVetoException " );
308             throw RuntimeException( temp.concat( e.Message ),
309                 Reference< XInterface > () );
310         }
311         catch ( lang::IllegalArgumentException  & e )
312         {
313             OUString temp = OUSTR(
314                 "ScriptNameResolverImpl::resolve : IllegalArgumentException " );
315             throw lang::IllegalArgumentException( temp.concat( e.Message ),
316                 Reference< XInterface > (), e.ArgumentPosition );
317         }
318         catch ( lang::WrappedTargetException & e )
319         {
320 	    OUString temp = OUSTR(
321                 "ScriptNameResolverImpl::resolve : WrappedTargetException " );
322             throw RuntimeException( temp.concat( e.Message ),
323                 Reference< XInterface > () );
324         }
325         catch ( Exception & e )
326         {
327             OSL_TRACE(
328                 "Exception thrown by storage %d, failed to match uri: %s",
329                  *iter,
330                  ::rtl::OUStringToOString( e.Message,
331                  RTL_TEXTENCODING_ASCII_US ).pData->buffer );
332 	    OUString temp = OUSTR(
333                 "ScriptNameResolverImpl::resolve : unknown exception" );
334             throw RuntimeException( temp.concat( e.Message ),
335                 Reference< XInterface > () );
336         }
337 #ifdef _DEBUG
338         catch ( ... )
339         {
340             OSL_TRACE(
341                 "unknown exception thrown by storage %d, failed to match uri",
342                 *iter );
343 	    OUString temp = OUSTR(
344                 "ScriptNameResolverImpl::resolve Unknown exception caught - RuntimeException rethrown" );
345             throw RuntimeException( temp,
346                 Reference< XInterface > () );
347         }
348 #endif
349 
350     }
351     if ( !resolvedName.is() )
352     {
353         if( filesysScriptStorageID >  2 )
354         {
355             // get the filesys storage and dispose of it
356             Reference< XInterface > xScriptStorage( xScriptStorageMgr->getScriptStorage( filesysScriptStorageID ), UNO_SET_THROW );
357             Reference< storage::XScriptInfoAccess > xScriptInfoAccess = Reference<
358                 storage::XScriptInfoAccess > ( xScriptStorage, UNO_QUERY_THROW );
359             Sequence< Reference< storage::XScriptInfo > > results =
360                 xScriptInfoAccess->getAllImplementations( );
361             Reference < lang::XEventListener > xEL_ScriptStorageMgr(( xScriptStorageMgr ,UNO_QUERY_THROW );
362             lang::EventObject event( results[ 0 ] );
363             xEL_ScriptStorageMgr->disposing( event );
364         }
365         throw lang::IllegalArgumentException( OUSTR(
366             "ScriptNameResolverImpl::resolve: no script found for uri=" ).concat( scriptURI ),
367             Reference< XInterface > (), 0 );
368     }
369     return resolvedName;
370 }
371 
372 //*************************************************************************
373 OUString SAL_CALL
374 ScriptNameResolverImpl::getImplementationName( )
375 throw( RuntimeException )
376 {
377     return nrs_implName;
378 }
379 
380 //*************************************************************************
381 sal_Bool SAL_CALL
382 ScriptNameResolverImpl::supportsService( const OUString& serviceName )
383 throw( RuntimeException )
384 {
385     OUString const * pNames = nrs_serviceNames.getConstArray();
386     for ( sal_Int32 nPos = nrs_serviceNames.getLength(); nPos--; )
387     {
388         if ( serviceName.equals( pNames[ nPos ] ) )
389         {
390             return sal_True;
391         }
392     }
393     return sal_False;
394 }
395 
396 //*************************************************************************
397 
398 Reference< storage::XScriptInfo >
399 ScriptNameResolverImpl::resolveURIFromStorageID
400 ( sal_Int32 sid, const ::rtl::OUString & docURI,
401   const ::rtl::OUString& scriptURI )
402 SAL_THROW ( ( lang::IllegalArgumentException, css::security::AccessControlException, RuntimeException ) )
403 {
404     Reference< storage::XScriptInfo > resolvedScriptInfo;
405     scripting_constants::ScriptingConstantsPool& scriptingConstantsPool =
406         scripting_constants::ScriptingConstantsPool::instance();
407     if ( sid == scriptingConstantsPool.DOC_STORAGE_ID_NOT_SET )
408     {
409         OSL_TRACE( "@@@@ **** ScriptNameResolverImpl::resolve DOC_STORAGE_ID_NOT_SET" );
410         return resolvedScriptInfo;
411     }
412     try
413     {
414         OUString permissionURI = docURI;
415         OUString filesysString = OUString::createFromAscii( "location=filesystem" );
416         if ( scriptURI.indexOf( filesysString ) != -1 )
417         {
418             // in the case of filesys scripts we're checking whether the
419             // location of the script, rather than the location of the document,
420             // has execute permission
421             try
422             {
423                 permissionURI = getFilesysURL( scriptURI );
424             }
425             catch ( lang::IllegalArgumentException & e )
426             {
427                 OUString temp = OUSTR( "ScriptNameResolverImpl::resolveFromURI: " );
428                 throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() );
429             }
430         }
431         Reference< storage::XScriptInfoAccess > storage( getStorageInstance( sid, permissionURI ), UNO_SET_THROW );
432         Sequence< Reference< storage::XScriptInfo > > results =
433             storage->getImplementations( scriptURI );
434 
435         const sal_Int32 length = results.getLength();
436 
437         if ( !length )
438         {
439             return resolvedScriptInfo;
440         }
441 
442         OSL_TRACE( "ScriptNameResolverImpl::resolve Got some results..." );
443         // if we get results, just return first in list,
444         // storage has already matched language, function name etc. if
445         // that information was in the uri
446         resolvedScriptInfo = results[ 0 ];
447     }
448     catch ( css::security::AccessControlException & ace )
449     {
450         OUString temp = OUSTR(
451             "ScriptRuntimeManager::resolveURIFromStorageID AccessControlException: " );
452         throw css::security::AccessControlException( temp.concat( ace.Message ),
453                                               Reference< XInterface > (),
454                                                 ace.LackingPermission );
455     }
456     catch ( lang::IllegalArgumentException & iae )
457     {
458         OUString temp = OUSTR(
459             "ScriptRuntimeManager::resolveURIFromStorageID IllegalArgumentException: " );
460         throw lang::IllegalArgumentException( temp.concat( iae.Message ),
461                                               Reference< XInterface > (),
462                                               iae.ArgumentPosition );
463     }
464     catch ( RuntimeException & re )
465     {
466         OUString temp = OUSTR(
467             "ScriptRuntimeManager::resolveURIFromStorageID RuntimeException: " );
468         throw RuntimeException( temp.concat( re.Message ),
469                                 Reference< XInterface > () );
470     }
471     catch ( Exception & e )
472     {
473         OUString temp = OUSTR(
474             "ScriptNameResolverImpl::resolveURIFromStorageID : Exception caught - RuntimeException rethrown" );
475         throw RuntimeException( temp.concat( e.Message ),
476                                 Reference< XInterface > () );
477     }
478 #ifdef _DEBUG
479     catch ( ... )
480     {
481         throw RuntimeException( OUSTR(
482             "ScriptNameResolverImpl::resolveURIFromStorageID Unknown exception caught - RuntimeException rethrown" ),
483             Reference< XInterface > () );
484     }
485 #endif
486     return resolvedScriptInfo;
487 }
488 //*************************************************************************
489 
490 Reference< storage::XScriptInfoAccess >
491 
492 ScriptNameResolverImpl::getStorageInstance( sal_Int32 sid,
493 const ::rtl::OUString & permissionURI ) SAL_THROW ( ( RuntimeException, css::security::AccessControlException, lang::IllegalArgumentException ) )
494 {
495     Reference< storage::XScriptInfoAccess > xScriptInfoAccess;
496     try
497     {
498         Reference< XInterface > xInterface( m_xContext->getValueByName(
499                     OUString::createFromAscii( SCRIPTSTORAGEMANAGER_SERVICE ) ), UNO_QUERY_THROW );
500         // check that we have permissions for this storage
501         Reference< dcsssf::security::XScriptSecurity > xScriptSecurity( xInterface, UNO_QUERY_THROW );
502         scripting_constants::ScriptingConstantsPool& scriptingConstantsPool =
503                 scripting_constants::ScriptingConstantsPool::instance();
504         // if we dealing with a document storage (ie. not user or share
505         // we need to check the permission
506         if( ( sid != scriptingConstantsPool.USER_STORAGE_ID ) &&
507             ( sid != scriptingConstantsPool.SHARED_STORAGE_ID ) )
508         {
509             xScriptSecurity->checkPermission( permissionURI,
510                 OUString::createFromAscii( "execute" ) );
511             // if we get here, the checkPermission hasn't thrown an
512             // AccessControlException, ie. permission has been granted
513             OSL_TRACE( "ScriptNameResolverImpl::getStorageInstance: got execute permission for ID=%d", sid );
514         }
515         Reference< storage::XScriptStorageManager > xScriptStorageManager( xInterface, UNO_QUERY_THROW );
516         Reference< XInterface > xScriptStorage( ScriptStorageManager->getScriptStorage( sid ), UNO_SET_THROW );
517         xScriptInfoAccess.set( xScriptStorage, UNO_QUERY_THROW );
518     }
519     catch ( lang::IllegalArgumentException & e )
520     {
521         OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: " );
522         throw lang::IllegalArgumentException( temp.concat( e.Message ),
523             Reference< XInterface >(), e.ArgumentPosition );
524     }
525     catch ( css::security::AccessControlException & e )
526     {
527         OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: AccessControlException " );
528         throw css::security::AccessControlException( temp.concat( e.Message ), Reference< XInterface >(), e.LackingPermission );
529     }
530     catch ( RuntimeException & re )
531     {
532         OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: " );
533         throw RuntimeException( temp.concat( re.Message ), Reference< XInterface >() );
534     }
535     catch ( Exception & e )
536     {
537         OUString temp = OUSTR( "ScriptNameResolverImpl::getStorageInstance: " );
538         throw RuntimeException( temp.concat( e.Message ), Reference< XInterface >() );
539     }
540     return xScriptInfoAccess;
541 }
542 //*************************************************************************
543 OUString
544 ScriptNameResolverImpl::getFilesysURL( const OUString & scriptURI )
545 throw( lang::IllegalArgumentException )
546 {
547         OUString filePath;
548         OUString fileName;
549         OUString filesysString = OUString::createFromAscii( "location=filesystem" );
550         sal_Int32 locationPos = scriptURI.indexOf( filesysString );
551         // expect location=filesys:file:///foo/bar/myscript.bsh etc
552         // except the file url at this point is encoded
553         // so we should be ok searching for the '&'
554         sal_Int32 filesysStrLen = filesysString.getLength() + 1;
555         sal_Int32 endOfLocn = scriptURI.indexOf( '&', locationPos );
556         if (endOfLocn == -1 )
557         {
558                 filePath = scriptURI.copy( locationPos + filesysString.getLength() + 1 );
559         }
560         else
561         {
562                 filePath = scriptURI.copy( locationPos + filesysStrLen,
563                                 endOfLocn - locationPos - filesysStrLen );
564         }
565         //file name shoul also be encoded so again ok to search for '&'
566         OUString functionKey = OUString::createFromAscii( "function=" );
567         sal_Int32 functionKeyLength = functionKey.getLength();
568         sal_Int32 functionNamePos = scriptURI.indexOf( functionKey );
569         if ( functionNamePos > 0 )
570         {
571             sal_Int32 endOfFn = scriptURI.indexOf( '&', functionNamePos );
572             if ( endOfFn == -1 )
573             {
574                 fileName = scriptURI.copy( functionNamePos + functionKeyLength );
575             }
576             else
577             {
578                 fileName = scriptURI.copy( functionNamePos + functionKeyLength,
579                                 endOfFn - functionNamePos - functionKeyLength );
580             }
581         }
582         else
583         {
584             // we need to throw
585             OUString temp = OUSTR( "ScriptNameResolverImpl::getFilesysURL: error getting the filesysURL" );
586             throw lang::IllegalArgumentException( temp, Reference< XInterface >(), 0 );
587         }
588         filePath+=fileName;
589         OSL_TRACE( "ScriptNameResolverImpl::getFilesysURL: filesys URL = %s",
590                  ::rtl::OUStringToOString( filePath,
591                  RTL_TEXTENCODING_ASCII_US ).pData->buffer );
592         return filePath;
593 }
594 //*************************************************************************
595 Sequence<OUString> SAL_CALL
596 ScriptNameResolverImpl::getSupportedServiceNames( )
597 throw( RuntimeException )
598 {
599     return nrs_serviceNames;
600 }
601 
602 //*************************************************************************
603 Reference< XInterface > SAL_CALL scriptnri_create(
604     Reference< XComponentContext > const & xComponentContext )
605 SAL_THROW( ( Exception ) )
606 {
607     return ( cppu::OWeakObject * ) new ScriptNameResolverImpl( xComponentContext );
608 }
609 
610 //*************************************************************************
611 Sequence< OUString > scriptnri_getSupportedServiceNames() SAL_THROW( () )
612 {
613     return nrs_serviceNames;
614 }
615 
616 //*************************************************************************
617 OUString scriptnri_getImplementationName() SAL_THROW( () )
618 {
619     return nrs_implName;
620 }
621 } // namespace scripting_runtimemgr
622