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 .
21 #include <stardiv/uno/repos/implementationregistration.hxx>
22 #include <stardiv/uno/script/script.hxx>
23 #include <stardiv/uno/beans/exactname.hxx>
25 #include <rtl/ustring.hxx>
26 #include <osl/diagnose.h>
27 #include <usr/services.hxx>
28 #include <vcl/svapp.hxx>
29 #include <usr/ustring.hxx>
30 #include <usr/weak.hxx>
31 #include <osl/conditn.hxx>
35 using ::rtl::StringToOUString
;
37 #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM)
38 #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr()
46 * A Test root object !
54 MyPythonRoot() { m_iTestValue
= 15; }
55 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
56 void acquire() { OWeakObject::acquire(); }
57 void release() { OWeakObject::release(); }
58 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
61 XIntrospectionAccessRef
getIntrospection() const THROWS( (UsrSystemException
) )
62 { return XIntrospectionAccessRef(); }
64 UsrAny
invoke( const UString
& FunctionName
,
65 const Sequence
< UsrAny
>& Params
,
66 Sequence
< INT16
>& OutParamIndex
,
67 Sequence
< UsrAny
>& OutParam
)
68 THROWS( ( IllegalArgumentException
,
69 CannotConvertException
,
70 InvocationTargetException
,
71 UsrSystemException
) );
72 void setValue(const UString
& PropertyName
, const UsrAny
& Value
)
73 THROWS( ( UnknownPropertyException
,
74 CannotConvertException
,
75 InvocationTargetException
,
76 UsrSystemException
) );
78 UsrAny
getValue(const UString
& PropertyName
)
79 THROWS( ( UnknownPropertyException
,
80 UsrSystemException
) );
81 BOOL
hasMethod(const UString
& Name
) const THROWS( (UsrSystemException
) );
82 BOOL
hasProperty(const UString
& Name
) const THROWS( (UsrSystemException
) );
85 void getTestValueViaInout( int &inout
)
86 { inout
= m_iTestValue
; }
88 INT32
getTestValue() const
89 { return m_iTestValue
; }
91 void setTestValue( INT32 i
)
95 { fprintf( stderr
, "TestValue : %d\n" , getTestValue() ); }
97 void addTestValue( INT32 i
)
98 { m_iTestValue
+= i
; }
105 BOOL
MyPythonRoot::queryInterface( Uik aUik
, XInterfaceRef
&rOut
)
107 if( aUik
== XInvokation::getSmartUik() ) {
108 rOut
= ( XInvokation
* ) this;
111 return OWeakObject::queryInterface( aUik
, rOut
);
117 UsrAny
MyPythonRoot::invoke( const UString
& FunctionName
,
118 const Sequence
< UsrAny
>& Params
,
119 Sequence
< INT16
>& OutParamIndex
,
120 Sequence
< UsrAny
>& OutParam
)
121 THROWS( ( IllegalArgumentException
,
122 CannotConvertException
,
123 InvocationTargetException
,
124 UsrSystemException
) )
126 if( L
"printTestValue" == FunctionName
) {
129 else if( L
"addTestValue" == FunctionName
) {
130 addTestValue( Params
.getConstArray()[0].getINT32() );
132 else if( L
"getTestValueViaInout" == FunctionName
) {
133 int i
= Params
.getConstArray()[0].getINT32();
134 getTestValueViaInout( i
);
135 OutParam
.getArray()[0].setINT32( i
);
138 THROW( InvocationTargetException() );
144 void MyPythonRoot::setValue(const UString
& PropertyName
, const UsrAny
& Value
)
145 THROWS( ( UnknownPropertyException
,
146 CannotConvertException
,
147 InvocationTargetException
,
148 UsrSystemException
) )
150 if( L
"TestValue" == PropertyName
) {
151 setTestValue( Value
.getINT32() );
154 THROW( UnknownPropertyException() );
158 UsrAny
MyPythonRoot::getValue(const UString
& PropertyName
)
159 THROWS( ( UnknownPropertyException
,
160 UsrSystemException
) )
164 if( L
"TestValue" == PropertyName
) {
165 aRet
.setINT32( getTestValue() );
168 THROW( UnknownPropertyException() );
175 BOOL
MyPythonRoot::hasMethod(const UString
& Name
) const THROWS( (UsrSystemException
) )
177 if( L
"printTestValue" == Name
) {
180 else if( L
"addTestValue" == Name
) {
183 else if( L
"getTestValueViaInout" == Name
) {
190 BOOL
MyPythonRoot::hasProperty(const UString
& Name
) const THROWS( (UsrSystemException
) )
192 if( L
"TestValue" == Name
) {
202 * A test engine listener to check the debug interface
206 public XEngineListener
,
217 TestListener( XDebuggingRef
*p
)
224 if( m_pDebuggingRef
) {
229 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
230 void acquire() { OWeakObject::acquire(); }
231 void release() { OWeakObject::release(); }
232 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
235 void attach( XDebuggingRef
*p
)
243 virtual void disposing( const EventObject
&o
)
245 if( m_pDebuggingRef
) {
249 virtual void interrupt(const InterruptEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
253 virtual void running(const EventObject
& Evt
) THROWS( (UsrSystemException
) )
255 (*m_pDebuggingRef
)->stop();
257 m_aDebugCondition
.set();
260 virtual void finished(const FinishEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
262 m_aDebugCondition
.set();
269 osl::Condition m_aDebugCondition
;
270 XDebuggingRef
*m_pDebuggingRef
;
275 void TestListener::cmdLine()
277 // Condition is set by running listener
278 m_aDebugCondition
.wait();
279 m_aDebugCondition
.reset();
280 (*m_pDebuggingRef
)->doContinue();
281 m_aDebugCondition
.wait();
284 void TestListener::detach()
286 OSL_ASSERT( m_pDebuggingRef
);
291 BOOL
TestListener::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
293 if( aUik
== XEngineListener::getSmartUik() )
294 rOut
= (XEngineListener
*)this;
296 return OWeakObject::queryInterface( aUik
, rOut
);
301 void checkInvokation( const XInvokationRef
&xInvoke
)
305 // check exporting an object as an invokation
306 OSL_ASSERT( xInvoke
->hasProperty( L
"list" ) );
307 anyList
= xInvoke
->getValue( L
"list" );
309 OSL_ASSERT( anyList
.getReflection() == XInvokation_getReflection() );
310 XInvokationRef
*pRef
= ( XInvokationRef
* ) anyList
.get();
311 OSL_ASSERT( (*pRef
).is() );
313 OSL_ASSERT( (*pRef
)->hasMethod( L
"append" ) );
314 OSL_ASSERT( (*pRef
)->hasMethod( L
"count" ) );
316 Sequence
<UsrAny
> seq(1);
317 UsrAny
any( (INT32
) 1);
318 (seq
.getArray())[0] = any
;
320 any
= (*pRef
)->invoke( L
"count" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
321 int nOldSize
= any
.getINT32();
323 any
= (*pRef
)->invoke( L
"append" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
324 any
= (*pRef
)->invoke( L
"count" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
326 OSL_ASSERT( nOldSize
+ 1 == any
.getINT32() );
329 // just for testing !
330 class PythonCodeLibrary
:
331 public XLibraryAccess
,
335 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
336 void acquire() { OWeakObject::acquire(); }
337 void release() { OWeakObject::release(); }
338 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
341 virtual BOOL
isFunction(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
346 virtual BOOL
isValidPath(const UString
& PathName
) THROWS( (UsrSystemException
) )
351 virtual Sequence
< UString
> getModuleNames() THROWS( (UsrSystemException
) )
353 return Sequence
<UString
> ();
356 virtual UString
getModuleSource(const UString
& ModulName
) THROWS( (UsrSystemException
) )
358 if( ModulName
== L
"testmodul" ) {
359 return UString( L
"def testmethod():\n"
365 virtual Sequence
< BYTE
> getModuleCode(const UString
& ModuleName
) THROWS( (UsrSystemException
) )
367 return Sequence
< BYTE
> ();
370 virtual UString
getFunctionSource(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
374 virtual Sequence
< BYTE
> getFunctionCode(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
376 return Sequence
< BYTE
> ();
380 BOOL
PythonCodeLibrary::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
382 if( XLibraryAccess::getSmartUik() == aUik
) {
383 rOut
= (XLibraryAccess
* ) this;
386 return OWeakObject::queryInterface( aUik
, rOut
);
397 int SAL_CALL
main (int argc
, char **argv
)
399 // necessary startup code
400 XMultiServiceFactoryRef xSMgr
= createRegistryServiceManager();
401 registerUsrServices( xSMgr
);
402 setProcessServiceManager( xSMgr
);
404 XInterfaceRef x
= xSMgr
->createInstance( L
"stardiv.uno.repos.ImplementationRegistration" );
405 XImplementationRegistrationRef
xReg( x
, USR_QUERY
);
406 sal_Char szBuf
[1024];
408 ORealDynamicLoader::computeModuleName( "pythonengine", szBuf
, 1024 );
409 UString
aDllName( StringToOUString( szBuf
, CHARSET_SYSTEM
) );
410 xReg
->registerImplementation( L
"stardiv.loader.SharedLibrary", aDllName
, XSimpleRegistryRef() );
412 x
= xSMgr
->createInstance( L
"stardiv.script.Python" );
413 XEngineRef
xEngine( x
, USR_QUERY
);
414 XInvokationRef
xInvoke( x
, USR_QUERY
);
415 XDebuggingRef
xDebug( x
, USR_QUERY
);
417 XInterfaceRef
rRoot( (XInvokation
* )new MyPythonRoot
, USR_QUERY
);
418 xEngine
->setRoot( rRoot
);
421 // execute a simple script
422 xEngine
->run( L
"nIntTest = 5\n"
423 L
"list = [2,3,4]\n" , XInterfaceRef(), Sequence
<UsrAny
> () );
432 OSL_ASSERT( xInvoke
->hasProperty( L
"nIntTest" ) );
433 UsrAny any
= xInvoke
->getValue( L
"nIntTest" );
435 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
436 OSL_ASSERT( any
.getINT32() == 5 );
438 // simple test: set an int !
439 xInvoke
->setValue( L
"nIntTest" , UsrAny( (INT32
) 10 ) );
440 any
= xInvoke
->getValue( L
"nIntTest" );
442 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
443 OSL_ASSERT( any
.getINT32() == 10 );
446 // call a python method !
448 xEngine
->run( L
"def foo():\n"
449 L
" return 'this is foo'\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
450 OSL_ASSERT( xInvoke
->hasMethod( L
"foo" ) );
451 UsrAny any
= xInvoke
->invoke( L
"foo" ,
454 Sequence
<UsrAny
> () );
455 OSL_ASSERT( any
.getString() == L
"this is foo" );
459 // check exception handling !
462 xInvoke
->invoke( L
"foo" , Sequence
<UsrAny
>(1) , Sequence
<INT16
>(), Sequence
<UsrAny
> () );
463 // wrong number of arguments
466 catch ( IllegalArgumentException
& e
) {
468 catch ( InvocationTargetException
& e
) {
470 catch ( CannotConvertException
& e
) {
471 // empty any cannot be converted
475 // check InOut-Parameter
476 checkInvokation( xInvoke
);
480 * Check Introspection Access
484 XIntrospectionAccessRef xIntrospection
= xInvoke
->getIntrospection();
485 OSL_ASSERT( xIntrospection
.is() );
487 // no further test, simply call them
488 xIntrospection
->getMethods(0);
489 xIntrospection
->getProperties(0);
491 OSL_ASSERT( xIntrospection
->getSuppliedMethodConcepts() == 0 );
492 OSL_ASSERT( xIntrospection
->getSuppliedPropertyConcepts() == 0 );
494 Property prop
= xIntrospection
->getProperty( L
"nIntTest" ,0 );
495 OSL_ASSERT( prop
.Name
== L
"nIntTest" );
496 OSL_ASSERT( prop
.Type
->getTypeClass() == TypeClass_LONG
);
498 XIdlMethodRef method
= xIntrospection
->getMethod( L
"foo" , 0 );
499 OSL_ASSERT( method
->getName() == L
"foo" );
505 * Multithreading test
514 // stop/doContinue + runAsync listener
516 // test hangs, if something is wrong
518 TestListener
*pListener
= new TestListener( &xDebug
);
519 XEngineListenerRef
ref( (XEngineListener
* ) pListener
, USR_QUERY
);
521 // single listener check !
522 xEngine
->runAsync( L
"pass\n"
523 , XInterfaceRef() , Sequence
<UsrAny
> () , ref
);
524 pListener
->cmdLine();
527 // ListenerAdministration check !
529 // test hangs, if something is wrong
531 TestListener
*pListener
= new TestListener( &xDebug
);
532 XEngineListenerRef
ref( (XEngineListener
* ) pListener
, USR_QUERY
);
534 // engine listener check !
535 xEngine
->addEngineListener( ref
);
536 xEngine
->runAsync( L
"pass\n"
537 , XInterfaceRef() , Sequence
<UsrAny
> () , XEngineListenerRef() );
538 pListener
->cmdLine();
539 xEngine
->removeEngineListener( ref
);
543 // check the import mechanism
545 XLibraryAccessRef
xLibrary( ( XLibraryAccess
* ) new PythonCodeLibrary
, USR_QUERY
);
546 xEngine
->setLibraryAccess( xLibrary
);
548 xEngine
->run( L
"import testmodul\n"
549 L
"x = testmodul.testmethod()\n" , XInterfaceRef() , Sequence
<UsrAny
>() );
550 UsrAny any
= xInvoke
->getValue( L
"x" );
551 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
552 OSL_ASSERT( any
.getINT32() == 42 );
555 // check other imports
557 // Check, if the libraries are available at run time
558 xEngine
->run( L
"import math\n"
559 L
"dMathTest = math.exp(0)\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
561 OSL_ASSERT( xInvoke
->hasProperty( L
"dMathTest" ) );
562 UsrAny any
= xInvoke
->getValue( L
"dMathTest" );
564 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_DOUBLE
);
565 OSL_ASSERT( any
.getDouble() == 1. );
568 // Test connection to root object !
570 xEngine
->run( L
"x = stardiv.root.TestValue\n"
571 L
"y = stardiv.inout(5)\n"
572 L
"stardiv.root.getTestValueViaInout(y)\n"
573 L
"z = y.value\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
575 UsrAny any
= xInvoke
->getValue( L
"x" );
576 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
577 OSL_ASSERT( any
.getINT32() == 15 );
579 any
= xInvoke
->getValue( L
"z" );
580 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
581 OSL_ASSERT( any
.getINT32() == 15 );
584 // Test exactName interface
586 UsrAny any
= xInvoke
->getValue( L
"__builtins__" );
587 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_INTERFACE
);
589 XInvokationRef
rInv( *((XInterfaceRef
*) any
.get() ), USR_QUERY
);
590 OSL_ASSERT( rInv
.is() );
592 XExactNameRef
rName( *((XInterfaceRef
*) any
.get() ), USR_QUERY
);
593 OSL_ASSERT( rName
.is() );
595 UString str
= rName
->getExactName( L
"SYNTAXERROR" );
596 OSL_ASSERT( str
.len() );
600 // Test exactName interface of the engine itself
602 XExactNameRef
rName( xInvoke
, USR_QUERY
);
603 OSL_ASSERT( rName
.is() );
604 UString str
= rName
->getExactName( L
"STARDIV" );
605 OSL_ASSERT( str
.len() );
612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */