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