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 <tools/string.hxx>
32 #include <osl/conditn.hxx>
36 using ::rtl::StringToOUString
;
38 #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM)
39 #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr()
47 * A Test root object !
55 MyPythonRoot() { m_iTestValue
= 15; }
56 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
57 void acquire() { OWeakObject::acquire(); }
58 void release() { OWeakObject::release(); }
59 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
62 XIntrospectionAccessRef
getIntrospection(void) const THROWS( (UsrSystemException
) )
63 { return XIntrospectionAccessRef(); }
65 UsrAny
invoke( const UString
& FunctionName
,
66 const Sequence
< UsrAny
>& Params
,
67 Sequence
< INT16
>& OutParamIndex
,
68 Sequence
< UsrAny
>& OutParam
)
69 THROWS( ( IllegalArgumentException
,
70 CannotConvertException
,
71 InvocationTargetException
,
72 UsrSystemException
) );
73 void setValue(const UString
& PropertyName
, const UsrAny
& Value
)
74 THROWS( ( UnknownPropertyException
,
75 CannotConvertException
,
76 InvocationTargetException
,
77 UsrSystemException
) );
79 UsrAny
getValue(const UString
& PropertyName
)
80 THROWS( ( UnknownPropertyException
,
81 UsrSystemException
) );
82 BOOL
hasMethod(const UString
& Name
) const THROWS( (UsrSystemException
) );
83 BOOL
hasProperty(const UString
& Name
) const THROWS( (UsrSystemException
) );
86 void getTestValueViaInout( int &inout
)
87 { inout
= m_iTestValue
; }
89 INT32
getTestValue() const
90 { return m_iTestValue
; }
92 void setTestValue( INT32 i
)
96 { fprintf( stderr
, "TestValue : %d\n" , getTestValue() ); }
98 void addTestValue( INT32 i
)
99 { m_iTestValue
+= i
; }
106 BOOL
MyPythonRoot::queryInterface( Uik aUik
, XInterfaceRef
&rOut
)
108 if( aUik
== XInvokation::getSmartUik() ) {
109 rOut
= ( XInvokation
* ) this;
112 return OWeakObject::queryInterface( aUik
, rOut
);
118 UsrAny
MyPythonRoot::invoke( const UString
& FunctionName
,
119 const Sequence
< UsrAny
>& Params
,
120 Sequence
< INT16
>& OutParamIndex
,
121 Sequence
< UsrAny
>& OutParam
)
122 THROWS( ( IllegalArgumentException
,
123 CannotConvertException
,
124 InvocationTargetException
,
125 UsrSystemException
) )
127 if( L
"printTestValue" == FunctionName
) {
130 else if( L
"addTestValue" == FunctionName
) {
131 addTestValue( Params
.getConstArray()[0].getINT32() );
133 else if( L
"getTestValueViaInout" == FunctionName
) {
134 int i
= Params
.getConstArray()[0].getINT32();
135 getTestValueViaInout( i
);
136 OutParam
.getArray()[0].setINT32( i
);
139 THROW( InvocationTargetException() );
145 void MyPythonRoot::setValue(const UString
& PropertyName
, const UsrAny
& Value
)
146 THROWS( ( UnknownPropertyException
,
147 CannotConvertException
,
148 InvocationTargetException
,
149 UsrSystemException
) )
151 if( L
"TestValue" == PropertyName
) {
152 setTestValue( Value
.getINT32() );
155 THROW( UnknownPropertyException() );
159 UsrAny
MyPythonRoot::getValue(const UString
& PropertyName
)
160 THROWS( ( UnknownPropertyException
,
161 UsrSystemException
) )
165 if( L
"TestValue" == PropertyName
) {
166 aRet
.setINT32( getTestValue() );
169 THROW( UnknownPropertyException() );
176 BOOL
MyPythonRoot::hasMethod(const UString
& Name
) const THROWS( (UsrSystemException
) )
178 if( L
"printTestValue" == Name
) {
181 else if( L
"addTestValue" == Name
) {
184 else if( L
"getTestValueViaInout" == Name
) {
191 BOOL
MyPythonRoot::hasProperty(const UString
& Name
) const THROWS( (UsrSystemException
) )
193 if( L
"TestValue" == Name
) {
203 * A test engine listener to check the debug interface
207 public XEngineListener
,
218 TestListener( XDebuggingRef
*p
)
225 if( m_pDebuggingRef
) {
230 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
231 void acquire() { OWeakObject::acquire(); }
232 void release() { OWeakObject::release(); }
233 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
236 void attach( XDebuggingRef
*p
)
244 virtual void disposing( const EventObject
&o
)
246 if( m_pDebuggingRef
) {
250 virtual void interrupt(const InterruptEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
254 virtual void running(const EventObject
& Evt
) THROWS( (UsrSystemException
) )
256 (*m_pDebuggingRef
)->stop();
258 m_aDebugCondition
.set();
261 virtual void finished(const FinishEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
263 m_aDebugCondition
.set();
270 osl::Condition m_aDebugCondition
;
271 XDebuggingRef
*m_pDebuggingRef
;
276 void TestListener::cmdLine()
278 // Condition is set by running listener
279 m_aDebugCondition
.wait();
280 m_aDebugCondition
.reset();
281 (*m_pDebuggingRef
)->doContinue();
282 m_aDebugCondition
.wait();
285 void TestListener::detach()
287 OSL_ASSERT( m_pDebuggingRef
);
292 BOOL
TestListener::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
294 if( aUik
== XEngineListener::getSmartUik() )
295 rOut
= (XEngineListener
*)this;
297 return OWeakObject::queryInterface( aUik
, rOut
);
302 void checkInvokation( const XInvokationRef
&xInvoke
)
306 // check exporting an object as an invokation
307 OSL_ASSERT( xInvoke
->hasProperty( L
"list" ) );
308 anyList
= xInvoke
->getValue( L
"list" );
310 OSL_ASSERT( anyList
.getReflection() == XInvokation_getReflection() );
311 XInvokationRef
*pRef
= ( XInvokationRef
* ) anyList
.get();
312 OSL_ASSERT( (*pRef
).is() );
314 OSL_ASSERT( (*pRef
)->hasMethod( L
"append" ) );
315 OSL_ASSERT( (*pRef
)->hasMethod( L
"count" ) );
317 Sequence
<UsrAny
> seq(1);
318 UsrAny
any( (INT32
) 1);
319 (seq
.getArray())[0] = any
;
321 any
= (*pRef
)->invoke( L
"count" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
322 int nOldSize
= any
.getINT32();
324 any
= (*pRef
)->invoke( L
"append" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
325 any
= (*pRef
)->invoke( L
"count" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
327 OSL_ASSERT( nOldSize
+ 1 == any
.getINT32() );
330 // just for testing !
331 class PythonCodeLibrary
:
332 public XLibraryAccess
,
336 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
337 void acquire() { OWeakObject::acquire(); }
338 void release() { OWeakObject::release(); }
339 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
342 virtual BOOL
isFunction(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
347 virtual BOOL
isValidPath(const UString
& PathName
) THROWS( (UsrSystemException
) )
352 virtual Sequence
< UString
> getModuleNames(void) THROWS( (UsrSystemException
) )
354 return Sequence
<UString
> ();
357 virtual UString
getModuleSource(const UString
& ModulName
) THROWS( (UsrSystemException
) )
359 if( ModulName
== L
"testmodul" ) {
360 return UString( L
"def testmethod():\n"
366 virtual Sequence
< BYTE
> getModuleCode(const UString
& ModuleName
) THROWS( (UsrSystemException
) )
368 return Sequence
< BYTE
> ();
371 virtual UString
getFunctionSource(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
375 virtual Sequence
< BYTE
> getFunctionCode(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
377 return Sequence
< BYTE
> ();
381 BOOL
PythonCodeLibrary::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
383 if( XLibraryAccess::getSmartUik() == aUik
) {
384 rOut
= (XLibraryAccess
* ) this;
387 return OWeakObject::queryInterface( aUik
, rOut
);
398 int SAL_CALL
main (int argc
, char **argv
)
400 // necessary startup code
401 XMultiServiceFactoryRef xSMgr
= createRegistryServiceManager();
402 registerUsrServices( xSMgr
);
403 setProcessServiceManager( xSMgr
);
405 XInterfaceRef x
= xSMgr
->createInstance( L
"stardiv.uno.repos.ImplementationRegistration" );
406 XImplementationRegistrationRef
xReg( x
, USR_QUERY
);
407 sal_Char szBuf
[1024];
409 ORealDynamicLoader::computeModuleName( "pythonengine", szBuf
, 1024 );
410 UString
aDllName( StringToOUString( szBuf
, CHARSET_SYSTEM
) );
411 xReg
->registerImplementation( L
"stardiv.loader.SharedLibrary", aDllName
, XSimpleRegistryRef() );
413 x
= xSMgr
->createInstance( L
"stardiv.script.Python" );
414 XEngineRef
xEngine( x
, USR_QUERY
);
415 XInvokationRef
xInvoke( x
, USR_QUERY
);
416 XDebuggingRef
xDebug( x
, USR_QUERY
);
418 XInterfaceRef
rRoot( (XInvokation
* )new MyPythonRoot
, USR_QUERY
);
419 xEngine
->setRoot( rRoot
);
422 // execute a simple script
423 xEngine
->run( L
"nIntTest = 5\n"
424 L
"list = [2,3,4]\n" , XInterfaceRef(), Sequence
<UsrAny
> () );
433 OSL_ASSERT( xInvoke
->hasProperty( L
"nIntTest" ) );
434 UsrAny any
= xInvoke
->getValue( L
"nIntTest" );
436 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
437 OSL_ASSERT( any
.getINT32() == 5 );
439 // simple test: set an int !
440 xInvoke
->setValue( L
"nIntTest" , UsrAny( (INT32
) 10 ) );
441 any
= xInvoke
->getValue( L
"nIntTest" );
443 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
444 OSL_ASSERT( any
.getINT32() == 10 );
447 // call a python method !
449 xEngine
->run( L
"def foo():\n"
450 L
" return 'this is foo'\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
451 OSL_ASSERT( xInvoke
->hasMethod( L
"foo" ) );
452 UsrAny any
= xInvoke
->invoke( L
"foo" ,
455 Sequence
<UsrAny
> () );
456 OSL_ASSERT( any
.getString() == L
"this is foo" );
460 // check exception handling !
463 xInvoke
->invoke( L
"foo" , Sequence
<UsrAny
>(1) , Sequence
<INT16
>(), Sequence
<UsrAny
> () );
464 // wrong number of arguments
467 catch ( IllegalArgumentException
& e
) {
469 catch ( InvocationTargetException
& e
) {
471 catch ( CannotConvertException
& e
) {
472 // empty any cannot be converted
476 // check InOut-Parameter
477 checkInvokation( xInvoke
);
481 * Check Introspection Access
485 XIntrospectionAccessRef xIntrospection
= xInvoke
->getIntrospection();
486 OSL_ASSERT( xIntrospection
.is() );
488 // no further test, simply call them
489 xIntrospection
->getMethods(0);
490 xIntrospection
->getProperties(0);
492 OSL_ASSERT( xIntrospection
->getSuppliedMethodConcepts() == 0 );
493 OSL_ASSERT( xIntrospection
->getSuppliedPropertyConcepts() == 0 );
495 Property prop
= xIntrospection
->getProperty( L
"nIntTest" ,0 );
496 OSL_ASSERT( prop
.Name
== L
"nIntTest" );
497 OSL_ASSERT( prop
.Type
->getTypeClass() == TypeClass_LONG
);
499 XIdlMethodRef method
= xIntrospection
->getMethod( L
"foo" , 0 );
500 OSL_ASSERT( method
->getName() == L
"foo" );
506 * Multithreading test
515 // stop/doContinue + runAsync listener
517 // test hangs, if something is wrong
519 TestListener
*pListener
= new TestListener( &xDebug
);
520 XEngineListenerRef
ref( (XEngineListener
* ) pListener
, USR_QUERY
);
522 // single listener check !
523 xEngine
->runAsync( L
"pass\n"
524 , XInterfaceRef() , Sequence
<UsrAny
> () , ref
);
525 pListener
->cmdLine();
528 // ListenerAdministration check !
530 // test hangs, if something is wrong
532 TestListener
*pListener
= new TestListener( &xDebug
);
533 XEngineListenerRef
ref( (XEngineListener
* ) pListener
, USR_QUERY
);
535 // engine listener check !
536 xEngine
->addEngineListener( ref
);
537 xEngine
->runAsync( L
"pass\n"
538 , XInterfaceRef() , Sequence
<UsrAny
> () , XEngineListenerRef() );
539 pListener
->cmdLine();
540 xEngine
->removeEngineListener( ref
);
544 // check the import mechanism
546 XLibraryAccessRef
xLibrary( ( XLibraryAccess
* ) new PythonCodeLibrary
, USR_QUERY
);
547 xEngine
->setLibraryAccess( xLibrary
);
549 xEngine
->run( L
"import testmodul\n"
550 L
"x = testmodul.testmethod()\n" , XInterfaceRef() , Sequence
<UsrAny
>() );
551 UsrAny any
= xInvoke
->getValue( L
"x" );
552 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
553 OSL_ASSERT( any
.getINT32() == 42 );
556 // check other imports
558 // Check, if the libraries are available at run time
559 xEngine
->run( L
"import math\n"
560 L
"dMathTest = math.exp(0)\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
562 OSL_ASSERT( xInvoke
->hasProperty( L
"dMathTest" ) );
563 UsrAny any
= xInvoke
->getValue( L
"dMathTest" );
565 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_DOUBLE
);
566 OSL_ASSERT( any
.getDouble() == 1. );
569 // Test connection to root object !
571 xEngine
->run( L
"x = stardiv.root.TestValue\n"
572 L
"y = stardiv.inout(5)\n"
573 L
"stardiv.root.getTestValueViaInout(y)\n"
574 L
"z = y.value\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
576 UsrAny any
= xInvoke
->getValue( L
"x" );
577 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
578 OSL_ASSERT( any
.getINT32() == 15 );
580 any
= xInvoke
->getValue( L
"z" );
581 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
582 OSL_ASSERT( any
.getINT32() == 15 );
585 // Test exactName interface
587 UsrAny any
= xInvoke
->getValue( L
"__builtins__" );
588 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_INTERFACE
);
590 XInvokationRef
rInv( *((XInterfaceRef
*) any
.get() ), USR_QUERY
);
591 OSL_ASSERT( rInv
.is() );
593 XExactNameRef
rName( *((XInterfaceRef
*) any
.get() ), USR_QUERY
);
594 OSL_ASSERT( rName
.is() );
596 UString str
= rName
->getExactName( L
"SYNTAXERROR" );
597 OSL_ASSERT( str
.len() );
601 // Test exactName interface of the engine itself
603 XExactNameRef
rName( xInvoke
, USR_QUERY
);
604 OSL_ASSERT( rName
.is() );
605 UString str
= rName
->getExactName( L
"STARDIV" );
606 OSL_ASSERT( str
.len() );
613 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */