1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 #include <stardiv/uno/repos/implementationregistration.hxx>
32 #include <stardiv/uno/script/script.hxx>
33 #include <stardiv/uno/beans/exactname.hxx>
35 #include <rtl/ustring.hxx>
36 #include <vos/dynload.hxx>
37 #include <vos/diagnose.hxx>
38 #include <usr/services.hxx>
39 #include <vcl/svapp.hxx>
40 #include <usr/ustring.hxx>
41 #include <usr/weak.hxx>
42 #include <tools/string.hxx>
43 #include <vos/conditn.hxx>
49 #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM)
50 #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr()
58 * A Test root object !
66 MyPythonRoot() { m_iTestValue
= 15; }
67 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
68 void acquire() { OWeakObject::acquire(); }
69 void release() { OWeakObject::release(); }
70 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
73 XIntrospectionAccessRef
getIntrospection(void) const THROWS( (UsrSystemException
) )
74 { return XIntrospectionAccessRef(); }
76 UsrAny
invoke( const UString
& FunctionName
,
77 const Sequence
< UsrAny
>& Params
,
78 Sequence
< INT16
>& OutParamIndex
,
79 Sequence
< UsrAny
>& OutParam
)
80 THROWS( ( IllegalArgumentException
,
81 CannotConvertException
,
82 InvocationTargetException
,
83 UsrSystemException
) );
84 void setValue(const UString
& PropertyName
, const UsrAny
& Value
)
85 THROWS( ( UnknownPropertyException
,
86 CannotConvertException
,
87 InvocationTargetException
,
88 UsrSystemException
) );
90 UsrAny
getValue(const UString
& PropertyName
)
91 THROWS( ( UnknownPropertyException
,
92 UsrSystemException
) );
93 BOOL
hasMethod(const UString
& Name
) const THROWS( (UsrSystemException
) );
94 BOOL
hasProperty(const UString
& Name
) const THROWS( (UsrSystemException
) );
97 void getTestValueViaInout( int &inout
)
98 { inout
= m_iTestValue
; }
100 INT32
getTestValue() const
101 { return m_iTestValue
; }
103 void setTestValue( INT32 i
)
104 { m_iTestValue
= i
; }
106 void printTestValue()
107 { fprintf( stderr
, "TestValue : %d\n" , getTestValue() ); }
109 void addTestValue( INT32 i
)
110 { m_iTestValue
+= i
; }
117 BOOL
MyPythonRoot::queryInterface( Uik aUik
, XInterfaceRef
&rOut
)
119 if( aUik
== XInvokation::getSmartUik() ) {
120 rOut
= ( XInvokation
* ) this;
123 return OWeakObject::queryInterface( aUik
, rOut
);
129 UsrAny
MyPythonRoot::invoke( const UString
& FunctionName
,
130 const Sequence
< UsrAny
>& Params
,
131 Sequence
< INT16
>& OutParamIndex
,
132 Sequence
< UsrAny
>& OutParam
)
133 THROWS( ( IllegalArgumentException
,
134 CannotConvertException
,
135 InvocationTargetException
,
136 UsrSystemException
) )
138 if( L
"printTestValue" == FunctionName
) {
141 else if( L
"addTestValue" == FunctionName
) {
142 addTestValue( Params
.getConstArray()[0].getINT32() );
144 else if( L
"getTestValueViaInout" == FunctionName
) {
145 int i
= Params
.getConstArray()[0].getINT32();
146 getTestValueViaInout( i
);
147 OutParam
.getArray()[0].setINT32( i
);
150 THROW( InvocationTargetException() );
156 void MyPythonRoot::setValue(const UString
& PropertyName
, const UsrAny
& Value
)
157 THROWS( ( UnknownPropertyException
,
158 CannotConvertException
,
159 InvocationTargetException
,
160 UsrSystemException
) )
162 if( L
"TestValue" == PropertyName
) {
163 setTestValue( Value
.getINT32() );
166 THROW( UnknownPropertyException() );
170 UsrAny
MyPythonRoot::getValue(const UString
& PropertyName
)
171 THROWS( ( UnknownPropertyException
,
172 UsrSystemException
) )
176 if( L
"TestValue" == PropertyName
) {
177 aRet
.setINT32( getTestValue() );
180 THROW( UnknownPropertyException() );
187 BOOL
MyPythonRoot::hasMethod(const UString
& Name
) const THROWS( (UsrSystemException
) )
189 if( L
"printTestValue" == Name
) {
192 else if( L
"addTestValue" == Name
) {
195 else if( L
"getTestValueViaInout" == Name
) {
202 BOOL
MyPythonRoot::hasProperty(const UString
& Name
) const THROWS( (UsrSystemException
) )
204 if( L
"TestValue" == Name
) {
214 * A test engine listener to check the debug interface
218 public XEngineListener
,
229 TestListener( XDebuggingRef
*p
)
236 if( m_pDebuggingRef
) {
241 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
242 void acquire() { OWeakObject::acquire(); }
243 void release() { OWeakObject::release(); }
244 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
247 void attach( XDebuggingRef
*p
)
255 virtual void disposing( const EventObject
&o
)
257 if( m_pDebuggingRef
) {
261 virtual void interrupt(const InterruptEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
265 virtual void running(const EventObject
& Evt
) THROWS( (UsrSystemException
) )
267 (*m_pDebuggingRef
)->stop();
269 m_aDebugCondition
.set();
272 virtual void finished(const FinishEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
274 m_aDebugCondition
.set();
281 OCondition m_aDebugCondition
;
282 XDebuggingRef
*m_pDebuggingRef
;
287 void TestListener::cmdLine()
289 // Condition is set by running listener
290 m_aDebugCondition
.wait();
291 m_aDebugCondition
.reset();
292 (*m_pDebuggingRef
)->doContinue();
293 m_aDebugCondition
.wait();
296 void TestListener::detach()
298 OSL_ASSERT( m_pDebuggingRef
);
303 BOOL
TestListener::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
305 if( aUik
== XEngineListener::getSmartUik() )
306 rOut
= (XEngineListener
*)this;
308 return OWeakObject::queryInterface( aUik
, rOut
);
313 void checkInvokation( const XInvokationRef
&xInvoke
)
317 // check exporting an object as an invokation
318 OSL_ASSERT( xInvoke
->hasProperty( L
"list" ) );
319 anyList
= xInvoke
->getValue( L
"list" );
321 OSL_ASSERT( anyList
.getReflection() == XInvokation_getReflection() );
322 XInvokationRef
*pRef
= ( XInvokationRef
* ) anyList
.get();
323 OSL_ASSERT( (*pRef
).is() );
325 OSL_ASSERT( (*pRef
)->hasMethod( L
"append" ) );
326 OSL_ASSERT( (*pRef
)->hasMethod( L
"count" ) );
328 Sequence
<UsrAny
> seq(1);
329 UsrAny
any( (INT32
) 1);
330 (seq
.getArray())[0] = any
;
332 any
= (*pRef
)->invoke( L
"count" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
333 int nOldSize
= any
.getINT32();
335 any
= (*pRef
)->invoke( L
"append" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
336 any
= (*pRef
)->invoke( L
"count" , seq
, Sequence
<INT16
>(), Sequence
<UsrAny
>() );
338 OSL_ASSERT( nOldSize
+ 1 == any
.getINT32() );
341 // just for testing !
342 class PythonCodeLibrary
:
343 public XLibraryAccess
,
347 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
348 void acquire() { OWeakObject::acquire(); }
349 void release() { OWeakObject::release(); }
350 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
353 virtual BOOL
isFunction(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
358 virtual BOOL
isValidPath(const UString
& PathName
) THROWS( (UsrSystemException
) )
363 virtual Sequence
< UString
> getModuleNames(void) THROWS( (UsrSystemException
) )
365 return Sequence
<UString
> ();
368 virtual UString
getModuleSource(const UString
& ModulName
) THROWS( (UsrSystemException
) )
370 if( ModulName
== L
"testmodul" ) {
371 return UString( L
"def testmethod():\n"
377 virtual Sequence
< BYTE
> getModuleCode(const UString
& ModuleName
) THROWS( (UsrSystemException
) )
379 return Sequence
< BYTE
> ();
382 virtual UString
getFunctionSource(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
386 virtual Sequence
< BYTE
> getFunctionCode(const UString
& FunctionName
) THROWS( (UsrSystemException
) )
388 return Sequence
< BYTE
> ();
392 BOOL
PythonCodeLibrary::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
394 if( XLibraryAccess::getSmartUik() == aUik
) {
395 rOut
= (XLibraryAccess
* ) this;
398 return OWeakObject::queryInterface( aUik
, rOut
);
409 int __LOADONCALLAPI
main (int argc
, char **argv
)
411 // necessary startup code
412 XMultiServiceFactoryRef xSMgr
= createRegistryServiceManager();
413 registerUsrServices( xSMgr
);
414 setProcessServiceManager( xSMgr
);
416 XInterfaceRef x
= xSMgr
->createInstance( L
"stardiv.uno.repos.ImplementationRegistration" );
417 XImplementationRegistrationRef
xReg( x
, USR_QUERY
);
418 sal_Char szBuf
[1024];
420 ORealDynamicLoader::computeModuleName( "pythonengine", szBuf
, 1024 );
421 UString
aDllName( StringToOUString( szBuf
, CHARSET_SYSTEM
) );
422 xReg
->registerImplementation( L
"stardiv.loader.SharedLibrary", aDllName
, XSimpleRegistryRef() );
424 x
= xSMgr
->createInstance( L
"stardiv.script.Python" );
425 XEngineRef
xEngine( x
, USR_QUERY
);
426 XInvokationRef
xInvoke( x
, USR_QUERY
);
427 XDebuggingRef
xDebug( x
, USR_QUERY
);
429 XInterfaceRef
rRoot( (XInvokation
* )new MyPythonRoot
, USR_QUERY
);
430 xEngine
->setRoot( rRoot
);
433 // execute a simple script
434 xEngine
->run( L
"nIntTest = 5\n"
435 L
"list = [2,3,4]\n" , XInterfaceRef(), Sequence
<UsrAny
> () );
444 OSL_ASSERT( xInvoke
->hasProperty( L
"nIntTest" ) );
445 UsrAny any
= xInvoke
->getValue( L
"nIntTest" );
447 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
448 OSL_ASSERT( any
.getINT32() == 5 );
450 // simple test: set an int !
451 xInvoke
->setValue( L
"nIntTest" , UsrAny( (INT32
) 10 ) );
452 any
= xInvoke
->getValue( L
"nIntTest" );
454 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
455 OSL_ASSERT( any
.getINT32() == 10 );
458 // call a python method !
460 xEngine
->run( L
"def foo():\n"
461 L
" return 'this is foo'\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
462 OSL_ASSERT( xInvoke
->hasMethod( L
"foo" ) );
463 UsrAny any
= xInvoke
->invoke( L
"foo" ,
466 Sequence
<UsrAny
> () );
467 OSL_ASSERT( any
.getString() == L
"this is foo" );
471 // check exception handling !
474 xInvoke
->invoke( L
"foo" , Sequence
<UsrAny
>(1) , Sequence
<INT16
>(), Sequence
<UsrAny
> () );
475 // wrong number of arguments
478 catch ( IllegalArgumentException
& e
) {
480 catch ( InvocationTargetException
& e
) {
482 catch ( CannotConvertException
& e
) {
483 // empty any cannot be converted
487 // check InOut-Parameter
488 checkInvokation( xInvoke
);
492 * Check Introspection Access
496 XIntrospectionAccessRef xIntrospection
= xInvoke
->getIntrospection();
497 OSL_ASSERT( xIntrospection
.is() );
499 // no further test, simply call them
500 xIntrospection
->getMethods(0);
501 xIntrospection
->getProperties(0);
503 OSL_ASSERT( xIntrospection
->getSuppliedMethodConcepts() == 0 );
504 OSL_ASSERT( xIntrospection
->getSuppliedPropertyConcepts() == 0 );
506 Property prop
= xIntrospection
->getProperty( L
"nIntTest" ,0 );
507 OSL_ASSERT( prop
.Name
== L
"nIntTest" );
508 OSL_ASSERT( prop
.Type
->getTypeClass() == TypeClass_LONG
);
510 XIdlMethodRef method
= xIntrospection
->getMethod( L
"foo" , 0 );
511 OSL_ASSERT( method
->getName() == L
"foo" );
517 * Multithreading test
526 // stop/doContinue + runAsync listener
528 // test hangs, if something is wrong
530 TestListener
*pListener
= new TestListener( &xDebug
);
531 XEngineListenerRef
ref( (XEngineListener
* ) pListener
, USR_QUERY
);
533 // single listener check !
534 xEngine
->runAsync( L
"pass\n"
535 , XInterfaceRef() , Sequence
<UsrAny
> () , ref
);
536 pListener
->cmdLine();
539 // ListenerAdministration check !
541 // test hangs, if something is wrong
543 TestListener
*pListener
= new TestListener( &xDebug
);
544 XEngineListenerRef
ref( (XEngineListener
* ) pListener
, USR_QUERY
);
546 // engine listener check !
547 xEngine
->addEngineListener( ref
);
548 xEngine
->runAsync( L
"pass\n"
549 , XInterfaceRef() , Sequence
<UsrAny
> () , XEngineListenerRef() );
550 pListener
->cmdLine();
551 xEngine
->removeEngineListener( ref
);
555 // check the import mechanism
557 XLibraryAccessRef
xLibrary( ( XLibraryAccess
* ) new PythonCodeLibrary
, USR_QUERY
);
558 xEngine
->setLibraryAccess( xLibrary
);
560 xEngine
->run( L
"import testmodul\n"
561 L
"x = testmodul.testmethod()\n" , XInterfaceRef() , Sequence
<UsrAny
>() );
562 UsrAny any
= xInvoke
->getValue( L
"x" );
563 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
564 OSL_ASSERT( any
.getINT32() == 42 );
567 // check other imports
569 // Check, if the libraries are available at run time
570 xEngine
->run( L
"import math\n"
571 L
"dMathTest = math.exp(0)\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
573 OSL_ASSERT( xInvoke
->hasProperty( L
"dMathTest" ) );
574 UsrAny any
= xInvoke
->getValue( L
"dMathTest" );
576 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_DOUBLE
);
577 OSL_ASSERT( any
.getDouble() == 1. );
580 // Test connection to root object !
582 xEngine
->run( L
"x = stardiv.root.TestValue\n"
583 L
"y = stardiv.inout(5)\n"
584 L
"stardiv.root.getTestValueViaInout(y)\n"
585 L
"z = y.value\n" , XInterfaceRef() , Sequence
<UsrAny
> () );
587 UsrAny any
= xInvoke
->getValue( L
"x" );
588 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
589 OSL_ASSERT( any
.getINT32() == 15 );
591 any
= xInvoke
->getValue( L
"z" );
592 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_LONG
);
593 OSL_ASSERT( any
.getINT32() == 15 );
596 // Test exactName interface
598 UsrAny any
= xInvoke
->getValue( L
"__builtins__" );
599 OSL_ASSERT( any
.getReflection()->getTypeClass() == TypeClass_INTERFACE
);
601 XInvokationRef
rInv( *((XInterfaceRef
*) any
.get() ), USR_QUERY
);
602 OSL_ASSERT( rInv
.is() );
604 XExactNameRef
rName( *((XInterfaceRef
*) any
.get() ), USR_QUERY
);
605 OSL_ASSERT( rName
.is() );
607 UString str
= rName
->getExactName( L
"SYNTAXERROR" );
608 OSL_ASSERT( str
.len() );
612 // Test exactName interface of the engine itself
614 XExactNameRef
rName( xInvoke
, USR_QUERY
);
615 OSL_ASSERT( rName
.is() );
616 UString str
= rName
->getExactName( L
"STARDIV" );
617 OSL_ASSERT( str
.len() );