| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_extensions.hxx" |
| #include <stdio.h> |
| #include <stardiv/uno/repos/implementationregistration.hxx> |
| #include <stardiv/uno/script/script.hxx> |
| #include <stardiv/uno/beans/exactname.hxx> |
| |
| #include <rtl/ustring.hxx> |
| #include <vos/dynload.hxx> |
| #include <vos/diagnose.hxx> |
| #include <usr/services.hxx> |
| #include <vcl/svapp.hxx> |
| #include <usr/ustring.hxx> |
| #include <usr/weak.hxx> |
| #include <tools/string.hxx> |
| #include <vos/conditn.hxx> |
| |
| using namespace rtl; |
| using namespace vos; |
| using namespace usr; |
| |
| #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM) |
| #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr() |
| |
| |
| |
| |
| |
| /***** |
| * |
| * A Test root object ! |
| * |
| *****/ |
| class MyPythonRoot : |
| public XInvokation, |
| public OWeakObject |
| { |
| public: |
| MyPythonRoot() { m_iTestValue = 15; } |
| BOOL queryInterface( Uik aUik, XInterfaceRef & rOut ); |
| void acquire() { OWeakObject::acquire(); } |
| void release() { OWeakObject::release(); } |
| void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } |
| |
| public: |
| XIntrospectionAccessRef getIntrospection(void) const THROWS( (UsrSystemException) ) |
| { return XIntrospectionAccessRef(); } |
| |
| UsrAny invoke( const UString& FunctionName, |
| const Sequence< UsrAny >& Params, |
| Sequence< INT16 >& OutParamIndex, |
| Sequence< UsrAny >& OutParam) |
| THROWS( ( IllegalArgumentException, |
| CannotConvertException, |
| InvocationTargetException, |
| UsrSystemException) ); |
| void setValue(const UString& PropertyName, const UsrAny& Value) |
| THROWS( ( UnknownPropertyException, |
| CannotConvertException, |
| InvocationTargetException, |
| UsrSystemException) ); |
| |
| UsrAny getValue(const UString& PropertyName) |
| THROWS( ( UnknownPropertyException, |
| UsrSystemException) ); |
| BOOL hasMethod(const UString& Name) const THROWS( (UsrSystemException) ); |
| BOOL hasProperty(const UString& Name) const THROWS( (UsrSystemException) ); |
| |
| |
| void getTestValueViaInout( int &inout ) |
| { inout = m_iTestValue; } |
| |
| INT32 getTestValue() const |
| { return m_iTestValue; } |
| |
| void setTestValue( INT32 i ) |
| { m_iTestValue = i; } |
| |
| void printTestValue() |
| { fprintf( stderr, "TestValue : %d\n" , getTestValue() ); } |
| |
| void addTestValue( INT32 i ) |
| { m_iTestValue += i; } |
| |
| private: |
| |
| INT32 m_iTestValue; |
| }; |
| |
| BOOL MyPythonRoot::queryInterface( Uik aUik, XInterfaceRef &rOut ) |
| { |
| if( aUik == XInvokation::getSmartUik() ) { |
| rOut = ( XInvokation * ) this; |
| } |
| else { |
| return OWeakObject::queryInterface( aUik , rOut ); |
| } |
| return TRUE; |
| |
| } |
| |
| UsrAny MyPythonRoot::invoke( const UString& FunctionName, |
| const Sequence< UsrAny >& Params, |
| Sequence< INT16 >& OutParamIndex, |
| Sequence< UsrAny >& OutParam) |
| THROWS( ( IllegalArgumentException, |
| CannotConvertException, |
| InvocationTargetException, |
| UsrSystemException) ) |
| { |
| if( L"printTestValue" == FunctionName ) { |
| printTestValue(); |
| } |
| else if( L"addTestValue" == FunctionName ) { |
| addTestValue( Params.getConstArray()[0].getINT32() ); |
| } |
| else if( L"getTestValueViaInout" == FunctionName ) { |
| int i = Params.getConstArray()[0].getINT32(); |
| getTestValueViaInout( i ); |
| OutParam.getArray()[0].setINT32( i ); |
| } |
| else { |
| THROW( InvocationTargetException() ); |
| } |
| |
| return UsrAny(); |
| } |
| |
| void MyPythonRoot::setValue(const UString& PropertyName, const UsrAny& Value) |
| THROWS( ( UnknownPropertyException, |
| CannotConvertException, |
| InvocationTargetException, |
| UsrSystemException) ) |
| { |
| if( L"TestValue" == PropertyName ) { |
| setTestValue( Value.getINT32() ); |
| } |
| else { |
| THROW( UnknownPropertyException() ); |
| } |
| } |
| |
| UsrAny MyPythonRoot::getValue(const UString& PropertyName) |
| THROWS( ( UnknownPropertyException, |
| UsrSystemException) ) |
| { |
| UsrAny aRet; |
| |
| if( L"TestValue" == PropertyName ) { |
| aRet.setINT32( getTestValue() ); |
| } |
| else { |
| THROW( UnknownPropertyException() ); |
| } |
| |
| return aRet; |
| } |
| |
| |
| BOOL MyPythonRoot::hasMethod(const UString& Name) const THROWS( (UsrSystemException) ) |
| { |
| if( L"printTestValue" == Name ) { |
| return TRUE; |
| } |
| else if( L"addTestValue" == Name ) { |
| return TRUE; |
| } |
| else if( L"getTestValueViaInout" == Name ) { |
| return TRUE; |
| } |
| return FALSE; |
| } |
| |
| |
| BOOL MyPythonRoot::hasProperty(const UString& Name) const THROWS( (UsrSystemException) ) |
| { |
| if( L"TestValue" == Name ) { |
| return TRUE; |
| } |
| |
| return FALSE; |
| } |
| |
| |
| /***** |
| * |
| * A test engine listener to check the debug interface |
| * |
| *****/ |
| class TestListener : |
| public XEngineListener, |
| public OWeakObject |
| { |
| public: |
| |
| TestListener() |
| { |
| m_pDebuggingRef = 0; |
| } |
| |
| |
| TestListener( XDebuggingRef *p ) |
| { |
| attach( p ); |
| } |
| |
| ~TestListener() |
| { |
| if( m_pDebuggingRef ) { |
| detach(); |
| } |
| } |
| |
| BOOL queryInterface( Uik aUik, XInterfaceRef & rOut ); |
| void acquire() { OWeakObject::acquire(); } |
| void release() { OWeakObject::release(); } |
| void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } |
| |
| |
| void attach( XDebuggingRef *p ) |
| { |
| m_pDebuggingRef = p; |
| } |
| |
| void detach( ); |
| |
| |
| virtual void disposing( const EventObject &o ) |
| { |
| if( m_pDebuggingRef ) { |
| detach(); |
| } |
| } |
| virtual void interrupt(const InterruptEngineEvent& Evt) THROWS( (UsrSystemException) ) |
| { |
| } |
| |
| virtual void running(const EventObject& Evt) THROWS( (UsrSystemException) ) |
| { |
| (*m_pDebuggingRef)->stop(); |
| |
| m_aDebugCondition.set(); |
| } |
| |
| virtual void finished(const FinishEngineEvent& Evt) THROWS( (UsrSystemException) ) |
| { |
| m_aDebugCondition.set(); |
| } |
| |
| |
| void cmdLine(); |
| protected: |
| |
| OCondition m_aDebugCondition; |
| XDebuggingRef *m_pDebuggingRef; |
| }; |
| |
| |
| |
| void TestListener::cmdLine() |
| { |
| // Condition is set by running listener |
| m_aDebugCondition.wait(); |
| m_aDebugCondition.reset(); |
| (*m_pDebuggingRef)->doContinue(); |
| m_aDebugCondition.wait(); |
| } |
| |
| void TestListener::detach() |
| { |
| OSL_ASSERT( m_pDebuggingRef ); |
| |
| m_pDebuggingRef = 0; |
| } |
| |
| BOOL TestListener::queryInterface( Uik aUik, XInterfaceRef & rOut ) |
| { |
| if( aUik == XEngineListener::getSmartUik() ) |
| rOut = (XEngineListener*)this; |
| else |
| return OWeakObject::queryInterface( aUik, rOut ); |
| return TRUE; |
| } |
| |
| |
| void checkInvokation( const XInvokationRef &xInvoke ) |
| { |
| UsrAny anyList; |
| |
| // check exporting an object as an invokation |
| OSL_ASSERT( xInvoke->hasProperty( L"list" ) ); |
| anyList = xInvoke->getValue( L"list" ); |
| |
| OSL_ASSERT( anyList.getReflection() == XInvokation_getReflection() ); |
| XInvokationRef *pRef = ( XInvokationRef * ) anyList.get(); |
| OSL_ASSERT( (*pRef).is() ); |
| |
| OSL_ASSERT( (*pRef)->hasMethod( L"append" ) ); |
| OSL_ASSERT( (*pRef)->hasMethod( L"count" ) ); |
| |
| Sequence<UsrAny> seq(1); |
| UsrAny any( (INT32) 1); |
| (seq.getArray())[0] = any; |
| |
| any = (*pRef)->invoke( L"count" , seq , Sequence<INT16>(), Sequence<UsrAny>() ); |
| int nOldSize = any.getINT32(); |
| |
| any = (*pRef)->invoke( L"append" , seq , Sequence<INT16>(), Sequence<UsrAny>() ); |
| any = (*pRef)->invoke( L"count" , seq , Sequence<INT16>(), Sequence<UsrAny>() ); |
| |
| OSL_ASSERT( nOldSize + 1 == any.getINT32() ); |
| } |
| |
| // just for testing ! |
| class PythonCodeLibrary : |
| public XLibraryAccess, |
| public OWeakObject |
| { |
| |
| BOOL queryInterface( Uik aUik, XInterfaceRef & rOut ); |
| void acquire() { OWeakObject::acquire(); } |
| void release() { OWeakObject::release(); } |
| void* getImplementation(Reflection *p) { return OWeakObject::getImplementation(p); } |
| |
| |
| virtual BOOL isFunction(const UString& FunctionName) THROWS( (UsrSystemException) ) |
| { |
| return FALSE; |
| } |
| |
| virtual BOOL isValidPath(const UString& PathName) THROWS( (UsrSystemException) ) |
| { |
| return FALSE; |
| } |
| |
| virtual Sequence< UString > getModuleNames(void) THROWS( (UsrSystemException) ) |
| { |
| return Sequence<UString> (); |
| } |
| |
| virtual UString getModuleSource(const UString& ModulName) THROWS( (UsrSystemException) ) |
| { |
| if( ModulName == L"testmodul" ) { |
| return UString( L"def testmethod():\n" |
| L" return 42\n"); |
| } |
| return UString(); |
| } |
| |
| virtual Sequence< BYTE > getModuleCode(const UString& ModuleName) THROWS( (UsrSystemException) ) |
| { |
| return Sequence< BYTE > (); |
| } |
| |
| virtual UString getFunctionSource(const UString& FunctionName) THROWS( (UsrSystemException) ) |
| { |
| return UString(); |
| } |
| virtual Sequence< BYTE > getFunctionCode(const UString& FunctionName) THROWS( (UsrSystemException) ) |
| { |
| return Sequence< BYTE > (); |
| } |
| }; |
| |
| BOOL PythonCodeLibrary::queryInterface( Uik aUik, XInterfaceRef & rOut ) |
| { |
| if( XLibraryAccess::getSmartUik() == aUik ) { |
| rOut = (XLibraryAccess* ) this; |
| } |
| else { |
| return OWeakObject::queryInterface( aUik , rOut ); |
| } |
| |
| return TRUE; |
| } |
| |
| |
| |
| /* |
| * main. |
| */ |
| int __LOADONCALLAPI main (int argc, char **argv) |
| { |
| // necessary startup code |
| XMultiServiceFactoryRef xSMgr = createRegistryServiceManager(); |
| registerUsrServices( xSMgr ); |
| setProcessServiceManager( xSMgr ); |
| |
| XInterfaceRef x = xSMgr->createInstance( L"stardiv.uno.repos.ImplementationRegistration" ); |
| XImplementationRegistrationRef xReg( x, USR_QUERY ); |
| sal_Char szBuf[1024]; |
| |
| ORealDynamicLoader::computeModuleName( "pythonengine", szBuf, 1024 ); |
| UString aDllName( StringToOUString( szBuf, CHARSET_SYSTEM ) ); |
| xReg->registerImplementation( L"stardiv.loader.SharedLibrary", aDllName, XSimpleRegistryRef() ); |
| |
| x = xSMgr->createInstance( L"stardiv.script.Python" ); |
| XEngineRef xEngine( x, USR_QUERY ); |
| XInvokationRef xInvoke( x, USR_QUERY ); |
| XDebuggingRef xDebug( x , USR_QUERY ); |
| |
| XInterfaceRef rRoot( (XInvokation * )new MyPythonRoot , USR_QUERY ); |
| xEngine->setRoot( rRoot ); |
| |
| |
| // execute a simple script |
| xEngine->run( L"nIntTest = 5\n" |
| L"list = [2,3,4]\n" , XInterfaceRef(), Sequence<UsrAny> () ); |
| |
| /**** |
| * |
| * Xinvokation - Test |
| * |
| *****/ |
| // get/set an int ! |
| { |
| OSL_ASSERT( xInvoke->hasProperty( L"nIntTest" ) ); |
| UsrAny any = xInvoke->getValue( L"nIntTest" ); |
| |
| OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG ); |
| OSL_ASSERT( any.getINT32() == 5 ); |
| |
| // simple test: set an int ! |
| xInvoke->setValue( L"nIntTest" , UsrAny( (INT32) 10 ) ); |
| any = xInvoke->getValue( L"nIntTest" ); |
| |
| OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG ); |
| OSL_ASSERT( any.getINT32() == 10 ); |
| } |
| |
| // call a python method ! |
| { |
| xEngine->run( L"def foo():\n" |
| L" return 'this is foo'\n" , XInterfaceRef() , Sequence<UsrAny> () ); |
| OSL_ASSERT( xInvoke->hasMethod( L"foo" ) ); |
| UsrAny any = xInvoke->invoke( L"foo" , |
| Sequence<UsrAny>(), |
| Sequence<INT16>() , |
| Sequence<UsrAny> () ); |
| OSL_ASSERT( any.getString() == L"this is foo" ); |
| } |
| |
| |
| // check exception handling ! |
| { |
| try { |
| xInvoke->invoke( L"foo" , Sequence<UsrAny>(1) , Sequence<INT16>(), Sequence<UsrAny> () ); |
| // wrong number of arguments |
| OSL_ASSERT( 0 ); |
| } |
| catch ( IllegalArgumentException& e ) { |
| } |
| catch ( InvocationTargetException& e ) { |
| } |
| catch ( CannotConvertException& e ) { |
| // empty any cannot be converted |
| } |
| } |
| |
| // check InOut-Parameter |
| checkInvokation( xInvoke ); |
| |
| /******* |
| * |
| * Check Introspection Access |
| * |
| *******/ |
| { |
| XIntrospectionAccessRef xIntrospection = xInvoke->getIntrospection(); |
| OSL_ASSERT( xIntrospection.is() ); |
| |
| // no further test, simply call them |
| xIntrospection->getMethods(0); |
| xIntrospection->getProperties(0); |
| |
| OSL_ASSERT( xIntrospection->getSuppliedMethodConcepts() == 0 ); |
| OSL_ASSERT( xIntrospection->getSuppliedPropertyConcepts() == 0 ); |
| |
| Property prop = xIntrospection->getProperty( L"nIntTest" ,0 ); |
| OSL_ASSERT( prop.Name == L"nIntTest" ); |
| OSL_ASSERT( prop.Type->getTypeClass() == TypeClass_LONG ); |
| |
| XIdlMethodRef method = xIntrospection->getMethod( L"foo" , 0 ); |
| OSL_ASSERT( method->getName() == L"foo" ); |
| } |
| |
| |
| /****** |
| * |
| * Multithreading test |
| * |
| *******/ |
| |
| /****** |
| * |
| * XDebuggingTest |
| * |
| ******/ |
| // stop/doContinue + runAsync listener |
| { |
| // test hangs, if something is wrong |
| |
| TestListener *pListener = new TestListener( &xDebug ); |
| XEngineListenerRef ref( (XEngineListener * ) pListener , USR_QUERY ); |
| |
| // single listener check ! |
| xEngine->runAsync( L"pass\n" |
| , XInterfaceRef() , Sequence<UsrAny> () , ref ); |
| pListener->cmdLine(); |
| } |
| |
| // ListenerAdministration check ! |
| { |
| // test hangs, if something is wrong |
| |
| TestListener *pListener = new TestListener( &xDebug ); |
| XEngineListenerRef ref( (XEngineListener * ) pListener , USR_QUERY ); |
| |
| // engine listener check ! |
| xEngine->addEngineListener( ref ); |
| xEngine->runAsync( L"pass\n" |
| , XInterfaceRef() , Sequence<UsrAny> () , XEngineListenerRef() ); |
| pListener->cmdLine(); |
| xEngine->removeEngineListener( ref); |
| |
| } |
| |
| // check the import mechanism |
| { |
| XLibraryAccessRef xLibrary( ( XLibraryAccess * ) new PythonCodeLibrary , USR_QUERY ); |
| xEngine->setLibraryAccess( xLibrary ); |
| |
| xEngine->run( L"import testmodul\n" |
| L"x = testmodul.testmethod()\n" , XInterfaceRef() , Sequence<UsrAny>() ); |
| UsrAny any = xInvoke->getValue( L"x" ); |
| OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG ); |
| OSL_ASSERT( any.getINT32() == 42 ); |
| } |
| |
| // check other imports |
| { |
| // Check, if the libraries are available at run time |
| xEngine->run( L"import math\n" |
| L"dMathTest = math.exp(0)\n" , XInterfaceRef() , Sequence<UsrAny> () ); |
| |
| OSL_ASSERT( xInvoke->hasProperty( L"dMathTest" ) ); |
| UsrAny any = xInvoke->getValue( L"dMathTest" ); |
| |
| OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_DOUBLE ); |
| OSL_ASSERT( any.getDouble() == 1. ); |
| } |
| |
| // Test connection to root object ! |
| { |
| xEngine->run( L"x = stardiv.root.TestValue\n" |
| L"y = stardiv.inout(5)\n" |
| L"stardiv.root.getTestValueViaInout(y)\n" |
| L"z = y.value\n" , XInterfaceRef() , Sequence<UsrAny> () ); |
| |
| UsrAny any = xInvoke->getValue( L"x" ); |
| OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG ); |
| OSL_ASSERT( any.getINT32() == 15 ); |
| |
| any = xInvoke->getValue( L"z" ); |
| OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_LONG ); |
| OSL_ASSERT( any.getINT32() == 15 ); |
| } |
| |
| // Test exactName interface |
| { |
| UsrAny any = xInvoke->getValue( L"__builtins__" ); |
| OSL_ASSERT( any.getReflection()->getTypeClass() == TypeClass_INTERFACE ); |
| |
| XInvokationRef rInv( *((XInterfaceRef *) any.get() ), USR_QUERY ); |
| OSL_ASSERT( rInv.is() ); |
| |
| XExactNameRef rName( *((XInterfaceRef*) any.get() ), USR_QUERY ); |
| OSL_ASSERT( rName.is() ); |
| |
| UString str = rName->getExactName( L"SYNTAXERROR" ); |
| OSL_ASSERT( str.len() ); |
| } |
| |
| |
| // Test exactName interface of the engine itself |
| { |
| XExactNameRef rName( xInvoke , USR_QUERY ); |
| OSL_ASSERT( rName.is() ); |
| UString str = rName->getExactName( L"STARDIV" ); |
| OSL_ASSERT( str.len() ); |
| } |
| |
| |
| return 0; |
| } |
| |