1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ScriptStorageManager.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_scripting.hxx"
36 #include <cppuhelper/implementationentry.hxx>
37 #include <sal/config.h>
38 #include <rtl/uri.hxx>
40 #include <com/sun/star/ucb/XSimpleFileAccess.hpp>
41 #include <com/sun/star/util/XMacroExpander.hpp>
42 #include <com/sun/star/lang/XComponent.hpp>
43 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <com/sun/star/frame/XModel.hpp>
46 #include <drafts/com/sun/star/script/framework/storage/XScriptInfoAccess.hpp>
48 #include "ScriptStorageManager.hxx"
49 #include <util/util.hxx>
50 #include <util/scriptingconstants.hxx>
52 using namespace ::rtl
;
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::drafts::com::sun::star::script::framework
;
57 namespace scripting_impl
60 static OUString s_implName
=
61 ::rtl::OUString::createFromAscii(
62 "drafts.com.sun.star.script.framework.storage.ScriptStorageManager" );
63 static OUString s_serviceName
=
64 ::rtl::OUString::createFromAscii(
65 "drafts.com.sun.star.script.framework.storage.ScriptStorageManager" );
66 static Sequence
< OUString
> s_serviceNames
= Sequence
< OUString
>( &s_serviceName
, 1 );
68 //extern ::rtl_StandardModuleCount s_moduleCount = MODULE_COUNT_INIT;
69 //extern ::rtl_StandardModuleCount s_moduleCount;
72 //*************************************************************************
73 // ScriptStorageManager Constructor
74 ScriptStorageManager::ScriptStorageManager( const Reference
<
75 XComponentContext
> & xContext
) SAL_THROW ( ( RuntimeException
) )
76 : m_xContext( xContext
), m_count( 0 ), m_securityMgr( xContext
)
78 OSL_TRACE( "< ScriptStorageManager ctor called >\n" );
79 //s_moduleCount.modCnt.acquire( &s_moduleCount.modCnt );
81 validateXRef( m_xContext
,
82 "ScriptStorageManager::ScriptStorageManager : cannot get component context" );
84 m_xMgr
= m_xContext
->getServiceManager();
86 "ScriptStorageManager::ScriptStorageManager : cannot get service manager" );
90 // obtain the macro expander singleton to use in determining the
91 // location of the application script storage
92 Any aAny
= m_xContext
->getValueByName( OUString::createFromAscii(
93 "/singletons/com.sun.star.util.theMacroExpander" ) );
94 Reference
< util::XMacroExpander
> xME
;
95 if ( sal_False
== ( aAny
>>= xME
) )
97 throw RuntimeException(
98 OUSTR( "ScriptStorageManager::ScriptStorageManager: can't get XMacroExpander" ),
99 Reference
< XInterface
>() );
101 validateXRef( xME
, "ScriptStorageManager constructor: can't get MacroExpander" );
103 OUString base
= OUString::createFromAscii(
104 SAL_CONFIGFILE( "${$BRAND_BASE_DIR/program/bootstrap" ) );
106 setupAppStorage( xME
,
107 base
.concat( OUString::createFromAscii( "::BaseInstallation}/share" ) ),
109 setupAppStorage( xME
,
110 base
.concat( OUString::createFromAscii( "::UserInstallation}/user" ) ),
114 catch ( Exception
& e
)
116 throw RuntimeException( OUSTR( "ScriptStorageManager::ScriptStorageManager: " ).concat( e
.Message
), Reference
< XInterface
>() );
118 OSL_ASSERT( m_count
== 2 );
121 //*************************************************************************
122 // ScriptStorageManager setupAppStorage
124 ScriptStorageManager::setupAppStorage(
125 const Reference
< util::XMacroExpander
> & xME
,
126 const OUString
& storageStr
,
127 const OUString
& appStr
)
128 SAL_THROW ( ( RuntimeException
) )
132 Reference
< XInterface
> xInterface
=
133 m_xMgr
->createInstanceWithContext(
134 OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), m_xContext
);
135 validateXRef( xInterface
,
136 "ScriptStorageManager constructor: can't get SimpleFileAccess XInterface" );
137 Reference
< ucb::XSimpleFileAccess
> xSFA( xInterface
, UNO_QUERY_THROW
);
139 setupAnyStorage( xSFA
, xME
->expandMacros( storageStr
), appStr
);
141 catch ( Exception
& e
)
143 throw RuntimeException(
144 OUSTR( "ScriptStorageManager::setupAppStorage: " ).concat( e
.Message
),
145 Reference
< XInterface
>() );
149 //*************************************************************************
150 // ScriptStorageManager setupAnyStorage
152 ScriptStorageManager::setupAnyStorage(
153 const Reference
< ucb::XSimpleFileAccess
> & xSFA
,
154 const OUString
& storageStr
,
155 const OUString
& origStringURI
)
156 SAL_THROW ( ( RuntimeException
) )
158 // Required for scope of fnc to protect all access read and writes to m_count
159 ::osl::Guard
< ::osl::Mutex
> aGuard( m_mutex
);
163 // create a ScriptingStorage using the SimpleFileAccess, the storageID
164 // (from the count), and the URL to the application's shared area
165 Sequence
< Any
> aArgs( 3 );
167 aArgs
[ 1 ] <<= m_count
;
168 aArgs
[ 2 ] <<= storageStr
;
170 OSL_TRACE( "creating storage for: %s\n",
171 ::rtl::OUStringToOString( storageStr
,
172 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
174 Reference
< XInterface
> xInterface
=
175 m_xMgr
->createInstanceWithArgumentsAndContext(
176 OUString::createFromAscii(
177 "drafts.com.sun.star.script.framework.storage.ScriptStorage" ),
180 validateXRef( xInterface
, "ScriptStorageManager:: setupAnyStorage: Can't create ScriptStorage for share" );
182 // and place it in the hash_map. Increment the counter
183 m_ScriptStorageMap
[ m_count
++ ] = xInterface
;
184 sal_Int32 sid
= m_count
- 1;
186 // create hash of original uri i.e. file:///home/users/docs/mydoc.sxw
187 // and storage id (sid) this will allow us to retrieve
188 // the sid based on the url of the document.
189 m_StorageIdOrigURIHash
[ origStringURI
] = sid
;
190 OSL_TRACE( "\tcreated with ID=%d\n", m_count
- 1 );
193 catch ( Exception
& e
)
195 throw RuntimeException(
196 OUSTR( "ScriptStorageManager::setupAnyStorage: " ).concat(
197 e
.Message
), Reference
< XInterface
>() );
203 //*************************************************************************
204 // ScriptStorageManager Destructor
205 ScriptStorageManager::~ScriptStorageManager()
208 OSL_TRACE( "< ScriptStorageManager dtor called >\n" );
209 // s_moduleCount.modCnt.release( &s_moduleCount.modCnt );
212 //*************************************************************************
213 // This method assumes that the XSimpleFileAccess knows it's on root URL
214 // and can be used with relative URLs
216 ScriptStorageManager::createScriptStorage(
217 const Reference
< ucb::XSimpleFileAccess
>& xSFA
)
218 throw ( RuntimeException
)
220 OSL_TRACE( "** ==> ScriptStorageManager in createScriptingStorage\n" );
222 "ScriptStorageManager::createScriptStorage: XSimpleFileAccess is not valid" );
224 return setupAnyStorage( xSFA
, ::rtl::OUString::createFromAscii( "" ),
225 ::rtl::OUString::createFromAscii( "" ) );
228 //*************************************************************************
230 ScriptStorageManager::createScriptStorageWithURI(
231 const Reference
< ucb::XSimpleFileAccess
>& xSFA
, const OUString
& cStringURI
)
232 throw ( RuntimeException
)
234 OSL_TRACE( "** ==> ScriptStorageManager in createScriptingStorageWithURI\n" );
235 validateXRef( xSFA
, "ScriptStorageManager::createScriptStorage: XSimpleFileAccess is not valid" );
237 // related to issue 11866
238 // warning dialog gets launched when adding binding to script in doc
239 // workaround issue: no functionProvider created on doc open
240 // if NODIALOG tag, strip from stringURI, set boolean=true
241 bool displayDialog
= true;
242 ::rtl::OUString dialogTag
= ::rtl::OUString::createFromAscii( "NoDialog::" );
243 ::rtl::OUString stringURI
= cStringURI
;
244 if( stringURI
.indexOf( dialogTag
) == 0 )
246 OSL_TRACE( "ScriptStorageManager::createScriptStorage: will not display security dialogs" );
247 stringURI
= stringURI
.copy( dialogTag
.getLength() );
248 displayDialog
= false;
250 sal_Int32 returnedID
= getScriptStorageID(stringURI
);
253 // convert file:///... url to vnd... syntax
254 ::rtl::OUString
canonicalURI(
255 ::rtl::OUString::createFromAscii( "vnd.sun.star.pkg://" ) );
256 canonicalURI
= canonicalURI
.concat( ::rtl::Uri::encode( stringURI
,
257 rtl_UriCharClassUricNoSlash
, rtl_UriEncodeCheckEscapes
,
258 RTL_TEXTENCODING_ASCII_US
) );
260 if (returnedID
== -1)
262 OSL_TRACE("Creating new storage for %s",
263 ::rtl::OUStringToOString( stringURI
,
264 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
265 returnedID
= setupAnyStorage( xSFA
, canonicalURI
, stringURI
);
269 OSL_TRACE("Using existing storage for %s",
270 ::rtl::OUStringToOString( stringURI
,
271 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
274 // np - removed previous scripting framework security handling
275 // now handled by modification to existing calls in sfx for basic
277 /* if( displayDialog )
281 OSL_TRACE("Adding to security mgr for %s",
282 ::rtl::OUStringToOString( stringURI,
283 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
284 m_securityMgr.addScriptStorage( stringURI, returnedID );
286 catch ( RuntimeException & rte )
288 throw RuntimeException(
289 OUSTR( "ScriptStorageManager::createScriptStorageWithURI: " ).concat(
290 rte.Message ), Reference< XInterface >() );
295 OSL_TRACE("No need to security mgr for %s",
296 ::rtl::OUStringToOString( stringURI,
297 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
302 //*************************************************************************
303 Reference
< XInterface
> SAL_CALL
304 ScriptStorageManager::getScriptStorage( sal_Int32 scriptStorageID
)
305 throw( RuntimeException
)
307 OSL_TRACE( "** ==> ScriptStorageManager in getStorageInstance\n" );
308 OSL_TRACE( "** ==> request for id=%d",scriptStorageID
);
310 ScriptStorage_map::const_iterator itr
=
311 m_ScriptStorageMap
.find( scriptStorageID
);
313 if ( itr
== m_ScriptStorageMap
.end() )
315 throw RuntimeException(
316 OUSTR( "ScriptStorageManager::getScriptStorage: invalid storage ID" ),
317 Reference
< XInterface
>() );
319 validateXRef( itr
->second
,
320 "ScriptStorageManager::getScriptStorage: Cannot get ScriptStorage from ScriptStorageHash" );
324 //*******************************************************************
326 ScriptStorageManager::getScriptStorageID( const ::rtl::OUString
& origURI
)
327 throw (::com::sun::star::uno::RuntimeException
)
329 StorageId_hash::const_iterator it
= m_StorageIdOrigURIHash
.find( origURI
);
331 if ( it
== m_StorageIdOrigURIHash
.end() )
333 OUString message
= OUSTR( "ScriptStorageManager::getScriptStorageID(): Cannot find storage for " );
334 if ( origURI
.getLength() == 0 )
336 message
= message
.concat( OUSTR("Empty URI") );
340 message
= message
.concat( origURI
);
342 OSL_TRACE( ::rtl::OUStringToOString( message
,
343 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
350 //*******************************************************************
352 ScriptStorageManager::removeScriptDocURIHashEntry( const OUString
& origURI
)
354 StorageId_hash::iterator it
= m_StorageIdOrigURIHash
.find( origURI
);
355 if ( it
== m_StorageIdOrigURIHash
.end() )
357 OSL_TRACE( "ScriptStorageManager::removeScriptDocURIHashEntry: no entry to remove" );
361 // remove entry for this doc url from orig uri map.
362 m_StorageIdOrigURIHash
.erase( it
);
365 //*******************************************************************
367 ScriptStorageManager::refreshScriptStorage( const OUString
& stringURI
)
368 throw( RuntimeException
)
370 OSL_TRACE( "** => ScriptStorageManager in refreshScriptStorage\n" );
371 OSL_TRACE( "** => refreshing URI: %s\n",
372 ::rtl::OUStringToOString(
373 stringURI
, RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
375 sal_Int32 storageID
= getScriptStorageID( stringURI
);
377 if ( storageID
== -1 )
379 OSL_TRACE( "** id was -1, no storage");
380 // Refreshing noexistent storage - just return
386 Reference
< storage::XScriptStorageRefresh
> xSSR(
387 getScriptStorage( storageID
), UNO_QUERY
);
391 catch ( RuntimeException
& e
)
393 throw RuntimeException(
394 OUSTR( "ScriptStorageManager::refreshScriptStorage: " ).concat(
395 e
.Message
), Reference
< XInterface
>() );
397 catch ( Exception
& e
)
399 throw RuntimeException(
400 OUSTR( "ScriptStorageManager::refreshScriptStorage: " ).concat(
401 e
.Message
), Reference
< XInterface
>() );
405 //*************************************************************************
407 ScriptStorageManager::checkPermission( const OUString
&
408 scriptStorageURI
, const OUString
& permissionRequest
)
409 throw ( RuntimeException
, lang::IllegalArgumentException
, css::security::AccessControlException
)
413 m_securityMgr
.checkPermission( scriptStorageURI
, permissionRequest
);
415 catch ( css::security::AccessControlException
& e
)
417 throw css::security::AccessControlException(
418 OUSTR( "ScriptStorageManager::checkPermission: AccessControlException: " ).concat(
419 e
.Message
), Reference
< XInterface
>(), e
.LackingPermission
);
421 catch ( lang::IllegalArgumentException
& e
)
423 throw lang::IllegalArgumentException(
424 OUSTR( "ScriptStorageManager::checkPermission: IllegalArgumentException: " ).concat(
425 e
.Message
), Reference
< XInterface
>(), e
.ArgumentPosition
);
427 catch ( RuntimeException
& e
)
429 throw RuntimeException(
430 OUSTR( "ScriptStorageManager::checkPermission: RuntimeException: " ).concat(
431 e
.Message
), Reference
< XInterface
>() );
435 //*************************************************************************
437 ScriptStorageManager::getImplementationName( )
438 throw( RuntimeException
)
443 //*************************************************************************
445 ScriptStorageManager::supportsService( const OUString
& serviceName
)
446 throw( RuntimeException
)
448 OUString
const * pNames
= s_serviceNames
.getConstArray();
449 for ( sal_Int32 nPos
= s_serviceNames
.getLength(); nPos
--; )
451 if ( serviceName
.equals( pNames
[ nPos
] ) )
459 //*************************************************************************
460 Sequence
< OUString
> SAL_CALL
461 ScriptStorageManager::getSupportedServiceNames( )
462 throw( RuntimeException
)
464 return s_serviceNames
;
467 //*************************************************************************
469 ScriptStorageManager::disposing( const ::com::sun::star::lang::EventObject
& Source
)
470 throw ( ::com::sun::star::uno::RuntimeException
)
472 OSL_TRACE( "ScriptStorageManager::disposing started" );
473 OSL_TRACE( "event object type=%s",
474 ::rtl::OUStringToOString( getCppuType( &Source
).getTypeName(),
475 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
477 bool removeSecurityPermission
= true;
480 Reference
< XInterface
> xInterface
= Source
.Source
;
481 // no UNO_QUERY_THROW since we want a 2nd change to query if it's
482 // not a document being disposed
483 Reference
< frame::XModel
> xModel
= Reference
< frame::XModel
> ( xInterface
, UNO_QUERY
);
486 storageURI
= xModel
->getURL();
490 // UNO_QURY_THROW here since it's supposed to be either a doc
491 // or a XScriptInfo (in the case of a filesys script)
492 Reference
< storage::XScriptInfo
> xScriptInfo
= Reference
< storage::XScriptInfo
> ( xInterface
, UNO_QUERY_THROW
);
493 storageURI
= xScriptInfo
->getParcelURI().concat( xScriptInfo
->getFunctionName() );
494 // to save the user seeing the security dialogs every time they
495 // run the script we hang on to the permission for a given script
496 // for the lifetime of the Office
497 removeSecurityPermission
= false;
498 // possibly need to encode it??
500 if ( storageURI
.getLength() > 0 )
502 OSL_TRACE( "URI disposing is ... %s",
503 ::rtl::OUStringToOString( storageURI
,
504 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
507 catch ( RuntimeException
& e
)
511 "ScriptStorageManager::disposing: can't get script context, reason = " );
512 message
= message
.concat( e
.Message
);
513 OSL_TRACE( ::rtl::OUStringToOString( message
,
514 RTL_TEXTENCODING_ASCII_US
).pData
->buffer
);
520 sal_Int32 scriptStorageID
= getScriptStorageID( storageURI
);
522 // no need to do anything if there's no doc storage
523 if( scriptStorageID
== -1 )
528 OSL_TRACE( "disposing storageID = %d", scriptStorageID
);
530 // attempt to get the storage from the hash to ensure that we have a
532 ScriptStorage_map::const_iterator itr
=
533 m_ScriptStorageMap
.find( scriptStorageID
);
535 if ( itr
== m_ScriptStorageMap
.end() )
537 OSL_TRACE( "Entry for storage id %d doesn't exist in map", scriptStorageID
);
541 // erase the entry from the hash
542 m_ScriptStorageMap
.erase( scriptStorageID
);
543 removeScriptDocURIHashEntry( storageURI
);
544 if ( removeSecurityPermission
)
546 m_securityMgr
.removePermissionSettings ( storageURI
);
551 namespace scripting_runtimemgr
553 //*************************************************************************
554 Reference
< XInterface
> SAL_CALL
556 const Reference
< XComponentContext
> & xCompC
)
558 return ( cppu::OWeakObject
* ) new ::scripting_impl::ScriptStorageManager( xCompC
);
561 //*************************************************************************
563 ssm_getSupportedServiceNames( )
566 return ::scripting_impl::s_serviceNames
;
569 //*************************************************************************
571 ssm_getImplementationName( )
574 return ::scripting_impl::s_implName
;