xref: /AOO41X/main/scripting/source/basprov/basscript.cxx (revision 2c6962431ffb1d162132ad55cb49d102a52ae3e3)
1*2c696243SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2c696243SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2c696243SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2c696243SAndrew Rist  * distributed with this work for additional information
6*2c696243SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2c696243SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2c696243SAndrew Rist  * "License"); you may not use this file except in compliance
9*2c696243SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*2c696243SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*2c696243SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2c696243SAndrew Rist  * software distributed under the License is distributed on an
15*2c696243SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2c696243SAndrew Rist  * KIND, either express or implied.  See the License for the
17*2c696243SAndrew Rist  * specific language governing permissions and limitations
18*2c696243SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*2c696243SAndrew Rist  *************************************************************/
21*2c696243SAndrew Rist 
22*2c696243SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_scripting.hxx"
26cdf0e10cSrcweir #include "basscript.hxx"
27cdf0e10cSrcweir #include <vos/mutex.hxx>
28cdf0e10cSrcweir #include <vcl/svapp.hxx>
29cdf0e10cSrcweir #include <basic/sbx.hxx>
30cdf0e10cSrcweir #include <basic/sbstar.hxx>
31cdf0e10cSrcweir #include <basic/sbmod.hxx>
32cdf0e10cSrcweir #include <basic/sbmeth.hxx>
33cdf0e10cSrcweir #include <basic/basmgr.hxx>
34cdf0e10cSrcweir #include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <map>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir 
39cdf0e10cSrcweir using namespace ::com::sun::star;
40cdf0e10cSrcweir using namespace ::com::sun::star::lang;
41cdf0e10cSrcweir using namespace ::com::sun::star::uno;
42cdf0e10cSrcweir using namespace ::com::sun::star::script;
43cdf0e10cSrcweir using namespace ::com::sun::star::document;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir extern ::com::sun::star::uno::Any sbxToUnoValue( SbxVariable* pVar );
46cdf0e10cSrcweir extern void unoToSbxValue( SbxVariable* pVar, const ::com::sun::star::uno::Any& aValue );
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //.........................................................................
50cdf0e10cSrcweir namespace basprov
51cdf0e10cSrcweir {
52cdf0e10cSrcweir //.........................................................................
53cdf0e10cSrcweir 
54cdf0e10cSrcweir     typedef ::std::map< sal_Int16, Any, ::std::less< sal_Int16 > > OutParamMap;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir     // =============================================================================
57cdf0e10cSrcweir     // BasicScriptImpl
58cdf0e10cSrcweir     // =============================================================================
59cdf0e10cSrcweir 
60cdf0e10cSrcweir     // -----------------------------------------------------------------------------
61cdf0e10cSrcweir 
BasicScriptImpl(const::rtl::OUString & funcName,SbMethodRef xMethod)62cdf0e10cSrcweir     BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName, SbMethodRef xMethod )
63cdf0e10cSrcweir         :m_xMethod( xMethod )
64cdf0e10cSrcweir         ,m_funcName( funcName )
65cdf0e10cSrcweir         ,m_documentBasicManager( NULL )
66cdf0e10cSrcweir         ,m_xDocumentScriptContext()
67cdf0e10cSrcweir     {
68cdf0e10cSrcweir     }
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     // -----------------------------------------------------------------------------
71cdf0e10cSrcweir 
BasicScriptImpl(const::rtl::OUString & funcName,SbMethodRef xMethod,BasicManager & documentBasicManager,const Reference<XScriptInvocationContext> & documentScriptContext)72cdf0e10cSrcweir     BasicScriptImpl::BasicScriptImpl( const ::rtl::OUString& funcName, SbMethodRef xMethod,
73cdf0e10cSrcweir         BasicManager& documentBasicManager, const Reference< XScriptInvocationContext >& documentScriptContext )
74cdf0e10cSrcweir         :m_xMethod( xMethod )
75cdf0e10cSrcweir         ,m_funcName( funcName )
76cdf0e10cSrcweir         ,m_documentBasicManager( &documentBasicManager )
77cdf0e10cSrcweir         ,m_xDocumentScriptContext( documentScriptContext )
78cdf0e10cSrcweir     {
79cdf0e10cSrcweir         StartListening( *m_documentBasicManager );
80cdf0e10cSrcweir     }
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     // -----------------------------------------------------------------------------
~BasicScriptImpl()83cdf0e10cSrcweir     BasicScriptImpl::~BasicScriptImpl()
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         if ( m_documentBasicManager )
86cdf0e10cSrcweir             EndListening( *m_documentBasicManager );
87cdf0e10cSrcweir     }
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     // -----------------------------------------------------------------------------
90cdf0e10cSrcweir     // SfxListener
91cdf0e10cSrcweir     // -----------------------------------------------------------------------------
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)92cdf0e10cSrcweir     void BasicScriptImpl::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
93cdf0e10cSrcweir     {
94cdf0e10cSrcweir         if ( &rBC != m_documentBasicManager )
95cdf0e10cSrcweir         {
96cdf0e10cSrcweir             OSL_ENSURE( false, "BasicScriptImpl::Notify: where does this come from?" );
97cdf0e10cSrcweir             // not interested in
98cdf0e10cSrcweir             return;
99cdf0e10cSrcweir         }
100cdf0e10cSrcweir         const SfxSimpleHint* pSimpleHint = PTR_CAST( SfxSimpleHint, &rHint );
101cdf0e10cSrcweir         if ( pSimpleHint && ( pSimpleHint->GetId() == SFX_HINT_DYING ) )
102cdf0e10cSrcweir         {
103cdf0e10cSrcweir             m_documentBasicManager = NULL;
104cdf0e10cSrcweir             EndListening( rBC );    // prevent multiple notifications
105cdf0e10cSrcweir         }
106cdf0e10cSrcweir     }
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     // -----------------------------------------------------------------------------
109cdf0e10cSrcweir     // XScript
110cdf0e10cSrcweir     // -----------------------------------------------------------------------------
111cdf0e10cSrcweir 
invoke(const Sequence<Any> & aParams,Sequence<sal_Int16> & aOutParamIndex,Sequence<Any> & aOutParam)112cdf0e10cSrcweir     Any BasicScriptImpl::invoke( const Sequence< Any >& aParams, Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam )
113cdf0e10cSrcweir         throw ( provider::ScriptFrameworkErrorException, reflection::InvocationTargetException, uno::RuntimeException)
114cdf0e10cSrcweir     {
115cdf0e10cSrcweir         // TODO: throw CannotConvertException
116cdf0e10cSrcweir         // TODO: check length of aOutParamIndex, aOutParam
117cdf0e10cSrcweir 
118cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
119cdf0e10cSrcweir 
120cdf0e10cSrcweir         Any aReturn;
121cdf0e10cSrcweir 
122cdf0e10cSrcweir         if ( m_xMethod )
123cdf0e10cSrcweir         {
124cdf0e10cSrcweir             // check if compiled
125cdf0e10cSrcweir             SbModule* pModule = static_cast< SbModule* >( m_xMethod->GetParent() );
126cdf0e10cSrcweir             if ( pModule && !pModule->IsCompiled() )
127cdf0e10cSrcweir                 pModule->Compile();
128cdf0e10cSrcweir 
129cdf0e10cSrcweir             // check number of parameters
130cdf0e10cSrcweir             sal_Int32 nParamsCount = aParams.getLength();
131cdf0e10cSrcweir             SbxInfo* pInfo = m_xMethod->GetInfo();
132cdf0e10cSrcweir             if ( pInfo )
133cdf0e10cSrcweir             {
134cdf0e10cSrcweir                 sal_Int32 nSbxOptional = 0;
135cdf0e10cSrcweir                 sal_uInt16 n = 1;
136cdf0e10cSrcweir                 for ( const SbxParamInfo* pParamInfo = pInfo->GetParam( n ); pParamInfo; pParamInfo = pInfo->GetParam( ++n ) )
137cdf0e10cSrcweir                 {
138cdf0e10cSrcweir                     if ( ( pParamInfo->nFlags & SBX_OPTIONAL ) != 0 )
139cdf0e10cSrcweir                         ++nSbxOptional;
140cdf0e10cSrcweir                     else
141cdf0e10cSrcweir                         nSbxOptional = 0;
142cdf0e10cSrcweir                 }
143cdf0e10cSrcweir                 sal_Int32 nSbxCount = n - 1;
144cdf0e10cSrcweir                 if ( nParamsCount < nSbxCount - nSbxOptional )
145cdf0e10cSrcweir                 {
146cdf0e10cSrcweir                     throw provider::ScriptFrameworkErrorException(
147cdf0e10cSrcweir                         ::rtl::OUString(
148cdf0e10cSrcweir                             RTL_CONSTASCII_USTRINGPARAM(
149cdf0e10cSrcweir                                 "wrong number of parameters!" ) ),
150cdf0e10cSrcweir                          Reference< XInterface >(),
151cdf0e10cSrcweir                          m_funcName,
152cdf0e10cSrcweir                          ::rtl::OUString(
153cdf0e10cSrcweir                              RTL_CONSTASCII_USTRINGPARAM( "Basic" ) ),
154cdf0e10cSrcweir                         provider::ScriptFrameworkErrorType::NO_SUCH_SCRIPT  );
155cdf0e10cSrcweir                 }
156cdf0e10cSrcweir             }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir             // set parameters
159cdf0e10cSrcweir             SbxArrayRef xSbxParams;
160cdf0e10cSrcweir             if ( nParamsCount > 0 )
161cdf0e10cSrcweir             {
162cdf0e10cSrcweir                 xSbxParams = new SbxArray;
163cdf0e10cSrcweir                 const Any* pParams = aParams.getConstArray();
164cdf0e10cSrcweir                 for ( sal_Int32 i = 0; i < nParamsCount; ++i )
165cdf0e10cSrcweir                 {
166cdf0e10cSrcweir                     SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT );
167cdf0e10cSrcweir                     unoToSbxValue( static_cast< SbxVariable* >( xSbxVar ), pParams[i] );
168cdf0e10cSrcweir                     xSbxParams->Put( xSbxVar, static_cast< sal_uInt16 >( i ) + 1 );
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 					// Enable passing by ref
171cdf0e10cSrcweir 					if ( xSbxVar->GetType() != SbxVARIANT )
172cdf0e10cSrcweir 						xSbxVar->SetFlag( SBX_FIXED );
173cdf0e10cSrcweir                  }
174cdf0e10cSrcweir             }
175cdf0e10cSrcweir             if ( xSbxParams.Is() )
176cdf0e10cSrcweir                 m_xMethod->SetParameters( xSbxParams );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir             // call method
179cdf0e10cSrcweir             SbxVariableRef xReturn = new SbxVariable;
180cdf0e10cSrcweir             ErrCode nErr = SbxERR_OK;
181cdf0e10cSrcweir             {
182cdf0e10cSrcweir                 // if it's a document-based script, temporarily reset ThisComponent to the script invocation context
183cdf0e10cSrcweir                 Any aOldThisComponent;
184cdf0e10cSrcweir                 if ( m_documentBasicManager && m_xDocumentScriptContext.is() )
185cdf0e10cSrcweir                     aOldThisComponent = m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", makeAny( m_xDocumentScriptContext ) );
186cdf0e10cSrcweir 
187cdf0e10cSrcweir                 nErr = m_xMethod->Call( xReturn );
188cdf0e10cSrcweir 
189cdf0e10cSrcweir                 if ( m_documentBasicManager && m_xDocumentScriptContext.is() )
190cdf0e10cSrcweir                     m_documentBasicManager->SetGlobalUNOConstant( "ThisComponent", aOldThisComponent );
191cdf0e10cSrcweir             }
192cdf0e10cSrcweir             if ( nErr != SbxERR_OK )
193cdf0e10cSrcweir             {
194cdf0e10cSrcweir                 // TODO: throw InvocationTargetException ?
195cdf0e10cSrcweir             }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir             // get output parameters
198cdf0e10cSrcweir             if ( xSbxParams.Is() )
199cdf0e10cSrcweir             {
200cdf0e10cSrcweir                 SbxInfo* pInfo_ = m_xMethod->GetInfo();
201cdf0e10cSrcweir                 if ( pInfo_ )
202cdf0e10cSrcweir                 {
203cdf0e10cSrcweir                     OutParamMap aOutParamMap;
204cdf0e10cSrcweir                     for ( sal_uInt16 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n )
205cdf0e10cSrcweir                     {
206cdf0e10cSrcweir                         const SbxParamInfo* pParamInfo = pInfo_->GetParam( n );
207cdf0e10cSrcweir                         if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 )
208cdf0e10cSrcweir                         {
209cdf0e10cSrcweir                             SbxVariable* pVar = xSbxParams->Get( n );
210cdf0e10cSrcweir                             if ( pVar )
211cdf0e10cSrcweir                             {
212cdf0e10cSrcweir                                 SbxVariableRef xVar = pVar;
213cdf0e10cSrcweir                                 aOutParamMap.insert( OutParamMap::value_type( n - 1, sbxToUnoValue( xVar ) ) );
214cdf0e10cSrcweir                             }
215cdf0e10cSrcweir                         }
216cdf0e10cSrcweir                     }
217cdf0e10cSrcweir                     sal_Int32 nOutParamCount = aOutParamMap.size();
218cdf0e10cSrcweir                     aOutParamIndex.realloc( nOutParamCount );
219cdf0e10cSrcweir                     aOutParam.realloc( nOutParamCount );
220cdf0e10cSrcweir                     sal_Int16* pOutParamIndex = aOutParamIndex.getArray();
221cdf0e10cSrcweir                     Any* pOutParam = aOutParam.getArray();
222cdf0e10cSrcweir                     for ( OutParamMap::iterator aIt = aOutParamMap.begin(); aIt != aOutParamMap.end(); ++aIt, ++pOutParamIndex, ++pOutParam )
223cdf0e10cSrcweir                     {
224cdf0e10cSrcweir                         *pOutParamIndex = aIt->first;
225cdf0e10cSrcweir                         *pOutParam = aIt->second;
226cdf0e10cSrcweir                     }
227cdf0e10cSrcweir                 }
228cdf0e10cSrcweir             }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir             // get return value
231cdf0e10cSrcweir             aReturn = sbxToUnoValue( xReturn );
232cdf0e10cSrcweir 
233cdf0e10cSrcweir             // reset parameters
234cdf0e10cSrcweir             m_xMethod->SetParameters( NULL );
235cdf0e10cSrcweir         }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir         return aReturn;
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     // -----------------------------------------------------------------------------
241cdf0e10cSrcweir 
242cdf0e10cSrcweir //.........................................................................
243cdf0e10cSrcweir }	// namespace basprov
244cdf0e10cSrcweir //.........................................................................
245