1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <cppuhelper/implementationentry.hxx>
21 #include <cppuhelper/factory.hxx>
22 #include <cppuhelper/implbase1.hxx>
23 #include <cppuhelper/exc_hlp.hxx>
24 #include <util/scriptingconstants.hxx>
25 #include <util/util.hxx>
26 #include <util/MiscUtils.hxx>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/util/XMacroExpander.hpp>
30 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
32 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
34 #include "MasterScriptProvider.hxx"
35 #include "ActiveMSPList.hxx"
37 #include <tools/diagnose_ex.h>
39 using namespace com::sun::star
;
40 using namespace com::sun::star::uno
;
41 using namespace com::sun::star::script
;
42 using namespace ::sf_misc
;
44 namespace func_provider
47 ActiveMSPList::ActiveMSPList( const Reference
< XComponentContext
> & xContext
) : m_xContext( xContext
)
49 userDirString
= OUString("user");
50 shareDirString
= OUString("share");
51 bundledDirString
= OUString("bundled");
54 ActiveMSPList::~ActiveMSPList()
58 Reference
< provider::XScriptProvider
>
59 ActiveMSPList::createNewMSP( const uno::Any
& context
)
61 OUString
serviceName("com.sun.star.script.provider.MasterScriptProvider");
62 Sequence
< Any
> args( &context
, 1 );
64 Reference
< provider::XScriptProvider
> msp(
65 m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(
66 serviceName
, args
, m_xContext
), UNO_QUERY
);
70 Reference
< provider::XScriptProvider
>
71 ActiveMSPList::getMSPFromAnyContext( const Any
& aContext
)
72 SAL_THROW(( lang::IllegalArgumentException
, RuntimeException
))
74 Reference
< provider::XScriptProvider
> msp
;
76 if ( aContext
>>= sContext
)
78 msp
= getMSPFromStringContext( sContext
);
82 Reference
< frame::XModel
> xModel( aContext
, UNO_QUERY
);
84 Reference
< document::XScriptInvocationContext
> xScriptContext( aContext
, UNO_QUERY
);
85 if ( xScriptContext
.is() )
89 // the component supports executing scripts embedded in a - possibly foreign document.
90 // Check whether this other document its the component itself.
91 if ( !xModel
.is() || ( xModel
!= xScriptContext
->getScriptContainer() ) )
93 msp
= getMSPFromInvocationContext( xScriptContext
);
97 catch( const lang::IllegalArgumentException
& )
99 xModel
.set( Reference
< frame::XModel
>() );
105 sContext
= MiscUtils::xModelToTdocUrl( xModel
, m_xContext
);
106 msp
= getMSPFromStringContext( sContext
);
111 return m_hMsps
[ shareDirString
];
114 Reference
< provider::XScriptProvider
>
115 ActiveMSPList::getMSPFromInvocationContext( const Reference
< document::XScriptInvocationContext
>& xContext
)
116 SAL_THROW(( lang::IllegalArgumentException
, RuntimeException
))
118 Reference
< provider::XScriptProvider
> msp
;
120 Reference
< document::XEmbeddedScripts
> xScripts
;
122 xScripts
.set( xContext
->getScriptContainer() );
123 if ( !xScripts
.is() )
126 buf
.appendAscii( "Failed to create MasterScriptProvider for ScriptInvocationContext: " );
127 buf
.appendAscii( "Component supporting XEmbeddScripts interface not found." );
128 throw lang::IllegalArgumentException( buf
.makeStringAndClear(), NULL
, 1 );
131 ::osl::MutexGuard
guard( m_mutex
);
133 Reference
< XInterface
> xNormalized( xContext
, UNO_QUERY
);
134 ScriptComponent_map::const_iterator pos
= m_mScriptComponents
.find( xNormalized
);
135 if ( pos
== m_mScriptComponents
.end() )
138 msp
= createNewMSP( uno::makeAny( xContext
) );
139 addActiveMSP( xNormalized
, msp
);
149 Reference
< provider::XScriptProvider
>
150 ActiveMSPList::getMSPFromStringContext( const OUString
& context
)
151 SAL_THROW(( lang::IllegalArgumentException
, RuntimeException
))
153 Reference
< provider::XScriptProvider
> msp
;
156 if ( context
.indexOf( "vnd.sun.star.tdoc" ) == 0 )
158 Reference
< frame::XModel
> xModel( MiscUtils::tDocUrlToModel( context
) );
160 Reference
< document::XEmbeddedScripts
> xScripts( xModel
, UNO_QUERY
);
161 Reference
< document::XScriptInvocationContext
> xScriptsContext( xModel
, UNO_QUERY
);
162 if ( !xScripts
.is() && !xScriptsContext
.is() )
165 buf
.appendAscii( "Failed to create MasterScriptProvider for '" );
166 buf
.append ( context
);
167 buf
.appendAscii( "': Either XEmbeddScripts or XScriptInvocationContext need to be supported by the document." );
168 throw lang::IllegalArgumentException( buf
.makeStringAndClear(), NULL
, 1 );
171 ::osl::MutexGuard
guard( m_mutex
);
172 Reference
< XInterface
> xNormalized( xModel
, UNO_QUERY
);
173 ScriptComponent_map::const_iterator pos
= m_mScriptComponents
.find( xNormalized
);
174 if ( pos
== m_mScriptComponents
.end() )
176 msp
= createNewMSP( context
);
177 addActiveMSP( xNormalized
, msp
);
186 ::osl::MutexGuard
guard( m_mutex
);
187 Msp_hash::iterator h_itEnd
= m_hMsps
.end();
188 Msp_hash::const_iterator itr
= m_hMsps
.find( context
);
189 if ( itr
== h_itEnd
)
191 msp
= createNewMSP( context
);
192 m_hMsps
[ context
] = msp
;
196 msp
= m_hMsps
[ context
];
200 catch( const lang::IllegalArgumentException
& )
204 catch( const RuntimeException
& )
208 catch( const Exception
& )
210 OUStringBuffer aMessage
;
211 aMessage
.appendAscii( "Failed to create MasterScriptProvider for context '" );
212 aMessage
.append ( context
);
213 aMessage
.appendAscii( "'." );
214 throw lang::WrappedTargetRuntimeException(
215 aMessage
.makeStringAndClear(), *this, ::cppu::getCaughtException() );
221 ActiveMSPList::addActiveMSP( const Reference
< uno::XInterface
>& xComponent
,
222 const Reference
< provider::XScriptProvider
>& msp
)
224 ::osl::MutexGuard
guard( m_mutex
);
225 Reference
< XInterface
> xNormalized( xComponent
, UNO_QUERY
);
226 ScriptComponent_map::const_iterator pos
= m_mScriptComponents
.find( xNormalized
);
227 if ( pos
== m_mScriptComponents
.end() )
229 m_mScriptComponents
[ xNormalized
] = msp
;
231 // add self as listener for component disposal
232 // should probably throw from this method!!, reexamine
235 Reference
< lang::XComponent
> xBroadcaster
=
236 Reference
< lang::XComponent
>( xComponent
, UNO_QUERY_THROW
);
237 xBroadcaster
->addEventListener( this );
239 catch ( const Exception
& )
241 DBG_UNHANDLED_EXCEPTION();
246 //*************************************************************************
248 ActiveMSPList::disposing( const ::com::sun::star::lang::EventObject
& Source
)
249 throw ( ::com::sun::star::uno::RuntimeException
)
254 Reference
< XInterface
> xNormalized( Source
.Source
, UNO_QUERY
);
255 if ( xNormalized
.is() )
257 ::osl::MutexGuard
guard( m_mutex
);
258 ScriptComponent_map::iterator pos
= m_mScriptComponents
.find( xNormalized
);
259 if ( pos
!= m_mScriptComponents
.end() )
260 m_mScriptComponents
.erase( pos
);
263 catch ( const Exception
& )
265 // if we get an exception here, there is not much we can do about
266 // it can't throw as it will screw up the model that is calling dispose
267 DBG_UNHANDLED_EXCEPTION();
273 ActiveMSPList::createNonDocMSPs()
275 static bool created
= false;
282 ::osl::MutexGuard
guard( m_mutex
);
287 // do creation of user and share MSPs here
288 OUString
serviceName("com.sun.star.script.provider.MasterScriptProvider");
289 Sequence
< Any
> args(1);
291 args
[ 0 ] <<= userDirString
;
292 Reference
< provider::XScriptProvider
> userMsp( m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName
, args
, m_xContext
), UNO_QUERY
);
293 // should check if provider reference is valid
294 m_hMsps
[ userDirString
] = userMsp
;
296 args
[ 0 ] <<= shareDirString
;
297 Reference
< provider::XScriptProvider
> shareMsp( m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName
, args
, m_xContext
), UNO_QUERY
);
298 // should check if provider reference is valid
299 m_hMsps
[ shareDirString
] = shareMsp
;
301 args
[ 0 ] <<= bundledDirString
;
302 Reference
< provider::XScriptProvider
> bundledMsp( m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext( serviceName
, args
, m_xContext
), UNO_QUERY
);
303 // should check if provider reference is valid
304 m_hMsps
[ bundledDirString
] = bundledMsp
;
312 } // namespace func_provider
314 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */