merge the formfield patch from ooo-build
[ooovba.git] / scripting / source / storage / ScriptStorageManager.cxx
blobff4b2bebe3fe2360e28497a51bdcb258bd3a2ef0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ScriptStorageManager.cxx,v $
10 * $Revision: 1.33 $
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"
34 #include <stdio.h>
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();
85 validateXRef( m_xMgr,
86 "ScriptStorageManager::ScriptStorageManager : cannot get service manager" );
88 try
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" ) ),
108 OUSTR( "SHARE" ) );
109 setupAppStorage( xME,
110 base.concat( OUString::createFromAscii( "::UserInstallation}/user" ) ),
111 OUSTR( "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
123 void
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
151 sal_Int32
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 );
166 aArgs[ 0 ] <<= xSFA;
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" ),
178 aArgs, m_xContext );
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 >() );
200 return m_count -1;
203 //*************************************************************************
204 // ScriptStorageManager Destructor
205 ScriptStorageManager::~ScriptStorageManager()
206 SAL_THROW ( () )
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
215 sal_Int32 SAL_CALL
216 ScriptStorageManager::createScriptStorage(
217 const Reference< ucb::XSimpleFileAccess >& xSFA )
218 throw ( RuntimeException )
220 OSL_TRACE( "** ==> ScriptStorageManager in createScriptingStorage\n" );
221 validateXRef( xSFA,
222 "ScriptStorageManager::createScriptStorage: XSimpleFileAccess is not valid" );
224 return setupAnyStorage( xSFA, ::rtl::OUString::createFromAscii( "" ),
225 ::rtl::OUString::createFromAscii( "" ) );
228 //*************************************************************************
229 sal_Int32 SAL_CALL
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 );
267 else
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 >() );
293 else
295 OSL_TRACE("No need to security mgr for %s",
296 ::rtl::OUStringToOString( stringURI,
297 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
299 return returnedID;
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" );
321 return itr->second;
324 //*******************************************************************
325 sal_Int32 SAL_CALL
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") );
338 else
340 message = message.concat( origURI );
342 OSL_TRACE( ::rtl::OUStringToOString( message,
343 RTL_TEXTENCODING_ASCII_US ).pData->buffer );
344 return -1;
347 return it->second;
350 //*******************************************************************
351 void
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" );
358 return;
361 // remove entry for this doc url from orig uri map.
362 m_StorageIdOrigURIHash.erase( it );
365 //*******************************************************************
366 void SAL_CALL
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
381 return;
386 Reference < storage::XScriptStorageRefresh > xSSR(
387 getScriptStorage( storageID ), UNO_QUERY );
389 xSSR->refresh();
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 //*************************************************************************
406 void SAL_CALL
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 //*************************************************************************
436 OUString SAL_CALL
437 ScriptStorageManager::getImplementationName( )
438 throw( RuntimeException )
440 return s_implName;
443 //*************************************************************************
444 sal_Bool SAL_CALL
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 ] ) )
453 return sal_True;
456 return sal_False;
459 //*************************************************************************
460 Sequence< OUString > SAL_CALL
461 ScriptStorageManager::getSupportedServiceNames( )
462 throw( RuntimeException )
464 return s_serviceNames;
467 //*************************************************************************
468 void SAL_CALL
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 );
476 OUString storageURI;
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 );
484 if( xModel.is() )
486 storageURI = xModel->getURL();
488 else
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 )
509 OUString message =
510 OUSTR(
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 );
515 return;
519 // grab storage id.
520 sal_Int32 scriptStorageID = getScriptStorageID( storageURI );
522 // no need to do anything if there's no doc storage
523 if( scriptStorageID == -1 )
525 return;
528 OSL_TRACE( "disposing storageID = %d", scriptStorageID );
530 // attempt to get the storage from the hash to ensure that we have a
531 // valid storageID
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 );
538 return;
541 // erase the entry from the hash
542 m_ScriptStorageMap.erase( scriptStorageID );
543 removeScriptDocURIHashEntry( storageURI );
544 if ( removeSecurityPermission )
546 m_securityMgr.removePermissionSettings ( storageURI );
549 } // Namespace
551 namespace scripting_runtimemgr
553 //*************************************************************************
554 Reference< XInterface > SAL_CALL
555 ssm_create(
556 const Reference< XComponentContext > & xCompC )
558 return ( cppu::OWeakObject * ) new ::scripting_impl::ScriptStorageManager( xCompC );
561 //*************************************************************************
562 Sequence< OUString >
563 ssm_getSupportedServiceNames( )
564 SAL_THROW( () )
566 return ::scripting_impl::s_serviceNames;
569 //*************************************************************************
570 OUString
571 ssm_getImplementationName( )
572 SAL_THROW( () )
574 return ::scripting_impl::s_implName;