summaryrefslogtreecommitdiff
path: root/pyuno/source
diff options
context:
space:
mode:
Diffstat (limited to 'pyuno/source')
-rw-r--r--pyuno/source/loader/makefile.mk112
-rw-r--r--pyuno/source/loader/pythonloader.py151
-rw-r--r--pyuno/source/loader/pyuno_loader.cxx248
-rw-r--r--pyuno/source/module/makefile.mk165
-rw-r--r--pyuno/source/module/pyuno4
-rw-r--r--pyuno/source/module/pyuno.cxx744
-rwxr-xr-xpyuno/source/module/pyuno.flt14
-rw-r--r--pyuno/source/module/pyuno_adapter.cxx437
-rw-r--r--pyuno/source/module/pyuno_callable.cxx273
-rw-r--r--pyuno/source/module/pyuno_dlopenwrapper.c60
-rw-r--r--pyuno/source/module/pyuno_except.cxx251
-rw-r--r--pyuno/source/module/pyuno_gc.cxx117
-rw-r--r--pyuno/source/module/pyuno_impl.hxx293
-rw-r--r--pyuno/source/module/pyuno_module.cxx717
-rw-r--r--pyuno/source/module/pyuno_runtime.cxx1058
-rw-r--r--pyuno/source/module/pyuno_type.cxx431
-rw-r--r--pyuno/source/module/pyuno_util.cxx249
-rw-r--r--pyuno/source/module/uno.py352
-rw-r--r--pyuno/source/module/unohelper.py304
19 files changed, 5980 insertions, 0 deletions
diff --git a/pyuno/source/loader/makefile.mk b/pyuno/source/loader/makefile.mk
new file mode 100644
index 000000000000..6f8648ce598e
--- /dev/null
+++ b/pyuno/source/loader/makefile.mk
@@ -0,0 +1,112 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=pyuno
+TARGET=pythonloader.uno
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
+DLLPRE =
+
+#-------------------------------------------------------------------
+
+.IF "$(OS)$(COMEX)" == "SOLARIS4"
+# no -Bdirect for SunWS CC
+DIRECT = $(LINKFLAGSDEFS)
+.ENDIF
+
+.IF "$(SYSTEM_PYTHON)" == "YES"
+PYTHONLIB=$(PYTHON_LIBS)
+CFLAGS+=$(PYTHON_CFLAGS)
+.IF "$(EXTRA_CFLAGS)"!=""
+PYTHONLIB+=-framework Python
+.ENDIF # "$(EXTRA_CFLAGS)"!=""
+.ELSE
+.INCLUDE : pyversion.mk
+
+CFLAGS+=-I$(SOLARINCDIR)$/python
+.ENDIF
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB) \
+ $(PYUNOLIB) \
+ $(PYTHONLIB)
+
+SHL1VERSIONMAP=$(SOLARENV)$/src$/component.map
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+SLOFILES= $(SLO)$/pyuno_loader.obj
+
+#COMPONENTS= \
+# tcv \
+# inv \
+# corefl \
+# insp \
+# invadp \
+# proxyfac \
+# pythonloader.uno \
+
+
+COMPONENTS= \
+ stocservices.uno \
+ invocation.uno \
+ introspection.uno \
+ invocadapt.uno \
+ proxyfac.uno \
+ reflection.uno \
+ .$/pythonloader.uno
+
+# --- Targets ------------------------------------------------------
+
+ALL : ALLTAR \
+ $(DLLDEST)$/pythonloader.py \
+ $(DLLDEST)$/pyuno_services.rdb
+.ENDIF # L10N_framework
+
+.INCLUDE : target.mk
+.IF "$(L10N_framework)"==""
+$(DLLDEST)$/%.py: %.py
+ cp $? $@
+
+$(DLLDEST)$/pyuno_services.rdb : makefile.mk $(DLLDEST)$/$(DLLPRE)$(TARGET)$(DLLPOST)
+ -rm -f $@ $(DLLDEST)$/pyuno_services.tmp $(DLLDEST)$/pyuno_services.rdb
+ cd $(DLLDEST) && $(REGCOMP) -register -r pyuno_services.tmp -wop $(foreach,i,$(COMPONENTS) -c $(i))
+ cd $(DLLDEST) && mv pyuno_services.tmp pyuno_services.rdb
+.ENDIF # L10N_framework
+
diff --git a/pyuno/source/loader/pythonloader.py b/pyuno/source/loader/pythonloader.py
new file mode 100644
index 000000000000..15fe57481f5a
--- /dev/null
+++ b/pyuno/source/loader/pythonloader.py
@@ -0,0 +1,151 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+import uno
+import unohelper
+import sys
+import imp
+import os
+from com.sun.star.uno import Exception,RuntimeException
+from com.sun.star.loader import XImplementationLoader
+from com.sun.star.lang import XServiceInfo
+
+MODULE_PROTOCOL = "vnd.openoffice.pymodule:"
+DEBUG = 0
+
+g_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader !
+g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader !
+
+def splitUrl( url ):
+ nColon = url.find( ":" )
+ if -1 == nColon:
+ raise RuntimeException( "PythonLoader: No protocol in url " + url, None )
+ return url[0:nColon], url[nColon+1:len(url)]
+
+g_loadedComponents = {}
+def checkForPythonPathBesideComponent( url ):
+ path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" );
+ if DEBUG == 1:
+ print "checking for existence of " + encfile( path )
+ if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path:
+ if DEBUG == 1:
+ print "adding " + encfile( path ) + " to sys.path"
+ sys.path.append( path )
+
+ path = unohelper.fileUrlToSystemPath( url+"/pythonpath" );
+ if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path:
+ if DEBUG == 1:
+ print "adding " + encfile( path ) + " to sys.path"
+ sys.path.append( path )
+
+def encfile(uni):
+ return uni.encode( sys.getfilesystemencoding())
+
+class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ):
+ def __init__(self, ctx ):
+ if DEBUG:
+ print "pythonloader.Loader ctor"
+ self.ctx = ctx
+
+ def getModuleFromUrl( self, url ):
+ if DEBUG:
+ print "pythonloader: interpreting url " +url
+ protocol, dependent = splitUrl( url )
+ if "vnd.sun.star.expand" == protocol:
+ exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" )
+ url = exp.expandMacros(dependent)
+ protocol,dependent = splitUrl( url )
+
+ if DEBUG:
+ print "pythonloader: after expansion " +protocol +":" + dependent
+
+ try:
+ if "file" == protocol:
+ # remove \..\ sequence, which may be useful e.g. in the build env
+ url = unohelper.absolutize( url, url )
+
+ # did we load the module already ?
+ mod = g_loadedComponents.get( url )
+ if not mod:
+ mod = imp.new_module("uno_component")
+
+ # check for pythonpath.zip beside .py files
+ checkForPythonPathBesideComponent( url[0:url.rfind('/')] )
+
+ # read the file
+ filename = unohelper.fileUrlToSystemPath( url )
+ fileHandle = file( filename )
+ src = fileHandle.read().replace("\r","")
+ if not src.endswith( "\n" ):
+ src = src + "\n"
+
+ # compile and execute the module
+ codeobject = compile( src, encfile(filename), "exec" )
+ exec codeobject in mod.__dict__
+ mod.__file__ = encfile(filename)
+ g_loadedComponents[url] = mod
+ return mod
+ elif "vnd.openoffice.pymodule" == protocol:
+ return __import__( dependent )
+ else:
+ raise RuntimeException( "PythonLoader: Unknown protocol " +
+ protocol + " in url " +url, self )
+ except ImportError, e:
+ raise RuntimeException( "Couldn't load "+url+ " for reason "+str(e), None)
+ return None
+
+ def activate( self, implementationName, dummy, locationUrl, regKey ):
+ if DEBUG:
+ print "pythonloader.Loader.activate"
+
+ mod = self.getModuleFromUrl( locationUrl )
+ implHelper = mod.__dict__.get( "g_ImplementationHelper" , None )
+ if implHelper == None:
+ return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey )
+ else:
+ return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager)
+
+ def writeRegistryInfo( self, regKey, dummy, locationUrl ):
+ if DEBUG:
+ print "pythonloader.Loader.writeRegistryInfo"
+
+ mod = self.getModuleFromUrl( locationUrl )
+ implHelper = mod.__dict__.get( "g_ImplementationHelper" , None )
+ if implHelper == None:
+ return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey )
+ else:
+ return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager )
+
+ def getImplementationName( self ):
+ return g_implementationName
+
+ def supportsService( self, ServiceName ):
+ return ServiceName in self.serviceNames
+
+ def getSupportedServiceNames( self ):
+ return g_supportedServices
+
+
diff --git a/pyuno/source/loader/pyuno_loader.cxx b/pyuno/source/loader/pyuno_loader.cxx
new file mode 100644
index 000000000000..57e893744f5f
--- /dev/null
+++ b/pyuno/source/loader/pyuno_loader.cxx
@@ -0,0 +1,248 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <pyuno/pyuno.hxx>
+
+#include <osl/process.h>
+#include <osl/file.h>
+#include <osl/thread.h>
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/bootstrap.hxx>
+
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/factory.hxx>
+
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using rtl::OString;
+
+using pyuno::PyRef;
+using pyuno::Runtime;
+using pyuno::PyThreadAttach;
+
+using com::sun::star::registry::XRegistryKey;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::XComponentContext;
+using com::sun::star::uno::RuntimeException;
+
+namespace pyuno_loader
+{
+
+static void raiseRuntimeExceptionWhenNeeded() throw ( RuntimeException )
+{
+ if( PyErr_Occurred() )
+ {
+ PyRef excType, excValue, excTraceback;
+ PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
+ Runtime runtime;
+ com::sun::star::uno::Any a = runtime.extractUnoException( excType, excValue, excTraceback );
+ OUStringBuffer buf;
+ buf.appendAscii( "python-loader:" );
+ if( a.hasValue() )
+ buf.append( ((com::sun::star::uno::Exception *)a.getValue())->Message );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
+ }
+}
+
+static PyRef getLoaderModule() throw( RuntimeException )
+{
+ PyRef module(
+ PyImport_ImportModule( const_cast< char * >("pythonloader") ),
+ SAL_NO_ACQUIRE );
+ raiseRuntimeExceptionWhenNeeded();
+ if( !module.is() )
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pythonloader: Couldn't load pythonloader module" ) ),
+ Reference< XInterface > () );
+ }
+ return PyRef( PyModule_GetDict( module.get() ));
+}
+
+static PyRef getObjectFromLoaderModule( const char * func )
+ throw ( RuntimeException )
+{
+ PyRef object( PyDict_GetItemString(getLoaderModule().get(), (char*)func ) );
+ if( !object.is() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pythonloader: couldn't find core element pythonloader." );
+ buf.appendAscii( func );
+ throw RuntimeException(buf.makeStringAndClear(),Reference< XInterface >());
+ }
+ return object;
+}
+
+OUString getImplementationName()
+{
+ return OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.pyuno.Loader" ) );
+}
+
+Sequence< OUString > getSupportedServiceNames()
+{
+ OUString serviceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Python" ) );
+ return Sequence< OUString > ( &serviceName, 1 );
+}
+
+static void setPythonHome ( const OUString & pythonHome )
+{
+ OUString systemPythonHome;
+ osl_getSystemPathFromFileURL( pythonHome.pData, &(systemPythonHome.pData) );
+ OString o = rtl::OUStringToOString( systemPythonHome, osl_getThreadTextEncoding() );
+ rtl_string_acquire(o.pData); // leak this string (thats the api!)
+ Py_SetPythonHome( o.pData->buffer);
+}
+
+static void prependPythonPath( const OUString & pythonPathBootstrap )
+{
+ rtl::OStringBuffer bufPYTHONPATH( 256 );
+ bufPYTHONPATH.append( "PYTHONPATH=");
+ sal_Int32 nIndex = 0;
+ while( 1 )
+ {
+ sal_Int32 nNew = pythonPathBootstrap.indexOf( ' ', nIndex );
+ OUString fileUrl;
+ if( nNew == -1 )
+ {
+ fileUrl = OUString( &( pythonPathBootstrap[nIndex] ) );
+ }
+ else
+ {
+ fileUrl = OUString( &(pythonPathBootstrap[nIndex]) , nNew - nIndex );
+ }
+ OUString systemPath;
+ osl_getSystemPathFromFileURL( fileUrl.pData, &(systemPath.pData) );
+ bufPYTHONPATH.append( rtl::OUStringToOString( systemPath.pData, osl_getThreadTextEncoding() ));
+ bufPYTHONPATH.append( SAL_PATHSEPARATOR );
+ if( nNew == -1 )
+ break;
+ nIndex = nNew + 1;
+ }
+ const char * oldEnv = getenv( "PYTHONPATH");
+ if( oldEnv )
+ bufPYTHONPATH.append( oldEnv );
+ OString result = bufPYTHONPATH.makeStringAndClear();
+ rtl_string_acquire( result.pData );
+
+// printf( "Setting %s\n" , result.pData->buffer );
+ putenv( result.pData->buffer );
+
+}
+
+Reference< XInterface > CreateInstance( const Reference< XComponentContext > & ctx )
+{
+ Reference< XInterface > ret;
+
+ if( ! Py_IsInitialized() )
+ {
+ OUString pythonPath;
+ OUString pythonHome;
+ OUString path( RTL_CONSTASCII_USTRINGPARAM( "$OOO_BASE_DIR/program/" SAL_CONFIGFILE("pythonloader.uno" )));
+ rtl::Bootstrap::expandMacros(path); //TODO: detect failure
+ rtl::Bootstrap bootstrap(path);
+
+ // look for pythonhome
+ bootstrap.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "PYUNO_LOADER_PYTHONHOME") ), pythonHome );
+ bootstrap.getFrom( OUString( RTL_CONSTASCII_USTRINGPARAM( "PYUNO_LOADER_PYTHONPATH" ) ) , pythonPath );
+
+ // pythonhome+pythonpath must be set before Py_Initialize(), otherwise there appear warning on the console
+ // sadly, there is no api for setting the pythonpath, we have to use the environment variable
+ if( pythonHome.getLength() )
+ setPythonHome( pythonHome );
+
+ if( pythonPath.getLength() )
+ prependPythonPath( pythonPath );
+
+ // initialize python
+ Py_Initialize();
+ PyEval_InitThreads();
+
+ PyThreadState *tstate = PyThreadState_Get();
+ PyEval_ReleaseThread( tstate );
+ }
+
+ PyThreadAttach attach( PyInterpreterState_Head() );
+ {
+ if( ! Runtime::isInitialized() )
+ {
+ Runtime::initialize( ctx );
+ }
+ Runtime runtime;
+
+ PyRef pyCtx = runtime.any2PyObject(
+ com::sun::star::uno::makeAny( ctx ) );
+
+ PyRef clazz = getObjectFromLoaderModule( "Loader" );
+ PyRef args ( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
+ PyTuple_SetItem( args.get(), 0 , pyCtx.getAcquired() );
+ PyRef pyInstance( PyObject_CallObject( clazz.get() , args.get() ), SAL_NO_ACQUIRE );
+ runtime.pyObject2Any( pyInstance ) >>= ret;
+ }
+ return ret;
+}
+
+}
+
+
+static struct cppu::ImplementationEntry g_entries[] =
+{
+ {
+ pyuno_loader::CreateInstance, pyuno_loader::getImplementationName,
+ pyuno_loader::getSupportedServiceNames, cppu::createSingleComponentFactory,
+ 0 , 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+sal_Bool SAL_CALL component_writeInfo(
+ void * pServiceManager, void * pRegistryKey )
+{
+ return cppu::component_writeInfoHelper( pServiceManager, pRegistryKey, g_entries );
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return cppu::component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+
+}
+
diff --git a/pyuno/source/module/makefile.mk b/pyuno/source/module/makefile.mk
new file mode 100644
index 000000000000..c928cc6f8e4c
--- /dev/null
+++ b/pyuno/source/module/makefile.mk
@@ -0,0 +1,165 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=pyuno
+TARGET=pyuno
+ENABLE_EXCEPTIONS=TRUE
+
+LINKFLAGSDEFS = # do not fail with missing symbols
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.IF "$(L10N_framework)"==""
+#-------------------------------------------------------------------
+
+.IF "$(OS)$(COMEX)" == "SOLARIS4"
+# no -Bdirect for SunWS CC
+DIRECT = $(LINKFLAGSDEFS)
+.ENDIF
+
+# special setting from environment
+.IF "$(EXTRA_CFLAGS)"!=""
+EXTRA_FRAMEWORK_FLAG=-framework Python
+.ENDIF # .IF "$(EXTRA_CFLAGS)"!=""
+
+.IF "$(GUI)" == "UNX"
+# python expects modules without the lib prefix
+# pyuno.so even on Mac OS X, because it is a python module
+PYUNO_MODULE=$(DLLDEST)$/pyuno.so
+PYUNORC=pyunorc
+.ELIF "$(GUI)" == "OS2"
+.INCLUDE : pyversion.mk
+PYUNORC=pyuno.ini
+.ELSE
+.INCLUDE : pyversion.mk
+PYUNORC=pyuno.ini
+DLLPOST=.pyd
+.ENDIF
+
+.IF "$(SYSTEM_PYTHON)" == "YES"
+PYTHONLIB=$(PYTHON_LIBS)
+CFLAGS+=$(PYTHON_CFLAGS)
+.ELSE # "$(SYSTEM_PYTHON)" == "YES"
+.INCLUDE : pyversion.mk
+CFLAGS+=-I$(SOLARINCDIR)$/python
+.ENDIF # "$(SYSTEM_PYTHON)" == "YES"
+
+SHL1TARGET=$(TARGET)
+SLOFILES= \
+ $(SLO)$/pyuno_runtime.obj \
+ $(SLO)$/pyuno.obj \
+ $(SLO)$/pyuno_callable.obj \
+ $(SLO)$/pyuno_module.obj \
+ $(SLO)$/pyuno_type.obj \
+ $(SLO)$/pyuno_util.obj \
+ $(SLO)$/pyuno_except.obj \
+ $(SLO)$/pyuno_adapter.obj \
+ $(SLO)$/pyuno_gc.obj
+
+# remove this, when issue i35064 is integrated
+.IF "$(COM)"=="GCC"
+NOOPTFILES= \
+ $(SLO)$/pyuno_module.obj
+.ENDIF # "$(COM)"=="GCC"
+
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB) \
+ $(PYTHONLIB) \
+ $(EXTRA_FRAMEWORK_FLAG)
+
+SHL1DEPN=
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1IMPLIB=i$(TARGET)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+DEF1DEPN= $(MISC)$/pyuno.flt
+
+DEFLIB1NAME=$(TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.IF "$(GUI)$(COM)"=="WNTGCC"
+ALLTAR : \
+ $(DLLDEST)$/uno.py \
+ $(DLLDEST)$/unohelper.py \
+ $(PYUNO_MODULE) \
+ $(MISC)$/$(PYUNORC) \
+ $(LB)$/lib$(TARGET).a
+
+$(LB)$/lib$(TARGET).a: $(MISC)$/$(TARGET).def
+ dlltool --dllname $(TARGET)$(DLLPOST) --input-def=$(MISC)$/$(TARGET).def --kill-at --output-lib=$(LB)$/lib$(TARGET).a
+.ELSE
+ALLTAR : \
+ $(DLLDEST)$/uno.py \
+ $(DLLDEST)$/unohelper.py \
+ $(PYUNO_MODULE) \
+ $(MISC)$/$(PYUNORC)
+.ENDIF
+.ENDIF
+
+.INCLUDE : target.mk
+.IF "$(L10N_framework)"==""
+$(DLLDEST)$/%.py: %.py
+ cp $? $@
+
+
+.IF "$(GUI)" == "UNX"
+$(PYUNO_MODULE) : $(SLO)$/pyuno_dlopenwrapper.obj
+.IF "$(OS)" == "LINUX"
+ @echo $(LINK) $(LINKFLAGS) $(LINKFLAGSRUNPATH_OOO) $(LINKFLAGSSHLCUI) -ldl -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "SOLARIS"
+ @echo ld -G -ldl -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "FREEBSD"
+ @echo ld -shared -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "NETBSD"
+ @echo $(LINK) $(LINKFLAGSSHLCUI) -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ELIF "$(OS)" == "MACOSX"
+ @echo $(CC) -bundle -ldl -o $@ $(SLO)$/pyuno_dlopenwrapper.o $(EXTRA_LINKFLAGS) $(EXTRA_FRAMEWORK_FLAG) > $(MISC)$/$(@:b).cmd
+.ELSE
+ @echo $(LINK) $(LINKFLAGSSHLCUI) -o $@ $(SLO)$/pyuno_dlopenwrapper.o > $(MISC)$/$(@:b).cmd
+.ENDIF
+ cat $(MISC)$/$(@:b).cmd
+ @+source $(MISC)$/$(@:b).cmd
+.ENDIF
+
+
+$(MISC)$/$(PYUNORC) : pyuno
+ -rm -f $@
+ cat pyuno > $@
+
+$(MISC)$/pyuno.flt : pyuno.flt
+ -rm -f $@
+ cat $? > $@
+.ENDIF # L10N_framework
+
diff --git a/pyuno/source/module/pyuno b/pyuno/source/module/pyuno
new file mode 100644
index 000000000000..5d13997bfde6
--- /dev/null
+++ b/pyuno/source/module/pyuno
@@ -0,0 +1,4 @@
+# The bootstrap variable PYUNOLIBDIR will be set by the pyuno runtime library
+PYUNO_BINPATH=$PYUNOLIBDIR/../bin$UPDMINOREXT
+UNO_TYPES=$PYUNO_BINPATH/types.rdb
+UNO_SERVICES=$PYUNO_BINPATH/pyuno_services.rdb
diff --git a/pyuno/source/module/pyuno.cxx b/pyuno/source/module/pyuno.cxx
new file mode 100644
index 000000000000..ef5b5673eae3
--- /dev/null
+++ b/pyuno/source/module/pyuno.cxx
@@ -0,0 +1,744 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "pyuno_impl.hxx"
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <osl/thread.h>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+
+#define TO_ASCII(x) OUStringToOString( x , RTL_TEXTENCODING_ASCII_US).getStr()
+
+using rtl::OStringBuffer;
+using rtl::OUStringBuffer;
+using rtl::OUStringToOString;
+using rtl::OUString;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::makeAny;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::Type;
+using com::sun::star::uno::TypeClass;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::Exception;
+using com::sun::star::uno::XComponentContext;
+using com::sun::star::lang::XSingleServiceFactory;
+using com::sun::star::lang::XServiceInfo;
+using com::sun::star::lang::XTypeProvider;
+using com::sun::star::script::XTypeConverter;
+using com::sun::star::script::XInvocation2;
+using com::sun::star::beans::XMaterialHolder;
+
+namespace pyuno
+{
+
+PyObject *PyUNO_str( PyObject * self );
+
+void PyUNO_del (PyObject* self)
+{
+ PyUNO* me = reinterpret_cast< PyUNO* > (self);
+ {
+ PyThreadDetach antiguard;
+ delete me->members;
+ }
+ PyObject_Del (self);
+}
+
+
+
+OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef , sal_Int32 mode ) SAL_THROW( () )
+{
+ OSL_ASSERT( pVal );
+ if (pTypeRef->eTypeClass == typelib_TypeClass_VOID)
+ return OUString( RTL_CONSTASCII_USTRINGPARAM("void") );
+
+ OUStringBuffer buf( 64 );
+ buf.append( (sal_Unicode)'(' );
+ buf.append( pTypeRef->pTypeName );
+ buf.append( (sal_Unicode)')' );
+
+ switch (pTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
+ buf.append( reinterpret_cast< sal_IntPtr >(*(void **)pVal), 16 );
+ if( VAL2STR_MODE_DEEP == mode )
+ {
+ buf.appendAscii( "{" ); Reference< XInterface > r = *( Reference< XInterface > * ) pVal;
+ Reference< XServiceInfo > serviceInfo( r, UNO_QUERY);
+ Reference< XTypeProvider > typeProvider(r,UNO_QUERY);
+ if( serviceInfo.is() )
+ {
+ buf.appendAscii("implementationName=" );
+ buf.append(serviceInfo->getImplementationName() );
+ buf.appendAscii(", supportedServices={" );
+ Sequence< OUString > seq = serviceInfo->getSupportedServiceNames();
+ for( int i = 0 ; i < seq.getLength() ; i ++ )
+ {
+ buf.append( seq[i] );
+ if( i +1 != seq.getLength() )
+ buf.appendAscii( "," );
+ }
+ buf.appendAscii("}");
+ }
+
+ if( typeProvider.is() )
+ {
+ buf.appendAscii(", supportedInterfaces={" );
+ Sequence< Type > seq (typeProvider->getTypes());
+ for( int i = 0 ; i < seq.getLength() ; i ++ )
+ {
+ buf.append(seq[i].getTypeName());
+ if( i +1 != seq.getLength() )
+ buf.appendAscii( "," );
+ }
+ buf.appendAscii("}");
+ }
+ buf.appendAscii( "}" );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ {
+// typelib_TypeDescription * pTypeDescr = 0;
+// TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
+// buf.append( val2str( (char *)pVal + ((typelib_UnionTypeDescription *)pTypeDescr)->nValueOffset,
+// union_getSetType( pVal, pTypeDescr ) ) );
+// buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
+// TYPELIB_DANGER_RELEASE( pTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+ OSL_ASSERT( pTypeDescr );
+
+ typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription *)pTypeDescr;
+ sal_Int32 nDescr = pCompType->nMembers;
+
+ if (pCompType->pBaseTypeDescription)
+ {
+ buf.append( val2str( pVal, ((typelib_TypeDescription *)pCompType->pBaseTypeDescription)->pWeakRef,mode ) );
+ if (nDescr)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ }
+
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
+ rtl_uString ** ppMemberNames = pCompType->ppMemberNames;
+
+ for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
+ {
+ buf.append( ppMemberNames[nPos] );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" = ") );
+ typelib_TypeDescription * pMemberType = 0;
+ TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
+ buf.append( val2str( (char *)pVal + pMemberOffsets[nPos], pMemberType->pWeakRef, mode ) );
+ TYPELIB_DANGER_RELEASE( pMemberType );
+ if (nPos < (nDescr -1))
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ }
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ uno_Sequence * pSequence = *(uno_Sequence **)pVal;
+ typelib_TypeDescription * pElementTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElementTypeDescr, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+
+ sal_Int32 nElementSize = pElementTypeDescr->nSize;
+ sal_Int32 nElements = pSequence->nElements;
+
+ if (nElements)
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
+ char * pElements = pSequence->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ buf.append( val2str( pElements + (nElementSize * nPos), pElementTypeDescr->pWeakRef, mode ) );
+ if (nPos < (nElements -1))
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
+ }
+ else
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{}") );
+ }
+ TYPELIB_DANGER_RELEASE( pElementTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("{ ") );
+ buf.append( val2str( ((uno_Any *)pVal)->pData,
+ ((uno_Any *)pVal)->pType ,
+ mode) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" }") );
+ break;
+ case typelib_TypeClass_TYPE:
+ buf.append( (*(typelib_TypeDescriptionReference **)pVal)->pTypeName );
+ break;
+ case typelib_TypeClass_STRING:
+ buf.append( (sal_Unicode)'\"' );
+ buf.append( *(rtl_uString **)pVal );
+ buf.append( (sal_Unicode)'\"' );
+ break;
+ case typelib_TypeClass_ENUM:
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ sal_Int32 * pValues = ((typelib_EnumTypeDescription *)pTypeDescr)->pEnumValues;
+ sal_Int32 nPos = ((typelib_EnumTypeDescription *)pTypeDescr)->nEnumValues;
+ while (nPos--)
+ {
+ if (pValues[nPos] == *(int *)pVal)
+ break;
+ }
+ if (nPos >= 0)
+ buf.append( ((typelib_EnumTypeDescription *)pTypeDescr)->ppEnumNames[nPos] );
+ else
+ buf.append( (sal_Unicode)'?' );
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ if (*(sal_Bool *)pVal)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("true") );
+ else
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("false") );
+ break;
+ case typelib_TypeClass_CHAR:
+ buf.append( (sal_Unicode)'\'' );
+ buf.append( *(sal_Unicode *)pVal );
+ buf.append( (sal_Unicode)'\'' );
+ break;
+ case typelib_TypeClass_FLOAT:
+ buf.append( *(float *)pVal );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ buf.append( *(double *)pVal );
+ break;
+ case typelib_TypeClass_BYTE:
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
+ buf.append( (sal_Int32)*(sal_Int8 *)pVal, 16 );
+ break;
+ case typelib_TypeClass_SHORT:
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
+ buf.append( (sal_Int32)*(sal_Int16 *)pVal, 16 );
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
+ buf.append( (sal_Int32)*(sal_uInt16 *)pVal, 16 );
+ break;
+ case typelib_TypeClass_LONG:
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
+ buf.append( *(sal_Int32 *)pVal, 16 );
+ break;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
+ buf.append( (sal_Int64)*(sal_uInt32 *)pVal, 16 );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("0x") );
+#if defined(GCC) && defined(SPARC)
+ {
+ sal_Int64 aVal;
+ *(sal_Int32 *)&aVal = *(sal_Int32 *)pVal;
+ *((sal_Int32 *)&aVal +1)= *((sal_Int32 *)pVal +1);
+ buf.append( aVal, 16 );
+ }
+#else
+ buf.append( *(sal_Int64 *)pVal, 16 );
+#endif
+ break;
+
+ case typelib_TypeClass_VOID:
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_UNKNOWN:
+ case typelib_TypeClass_SERVICE:
+ case typelib_TypeClass_MODULE:
+ default:
+ buf.append( (sal_Unicode)'?' );
+ }
+
+ return buf.makeStringAndClear();
+}
+
+
+PyObject *PyUNO_repr( PyObject * self )
+{
+ PyUNO *me = (PyUNO * ) self;
+ PyObject * ret = 0;
+
+ if( me->members->wrappedObject.getValueType().getTypeClass()
+ == com::sun::star::uno::TypeClass_EXCEPTION )
+ {
+ Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
+ if( rHolder.is() )
+ {
+ Any a = rHolder->getMaterial();
+ Exception e;
+ a >>= e;
+ ret = ustring2PyUnicode(e.Message ).getAcquired();
+ }
+ }
+ else
+ {
+ ret = PyUNO_str( self );
+ }
+ return ret;
+}
+
+PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args )
+{
+ PyRef ret;
+ try
+ {
+ Runtime runtime;
+
+ PyRef paras,callable;
+ if( PyObject_IsInstance( object, getPyUnoClass( runtime ).get() ) )
+ {
+ PyUNO* me = (PyUNO*) object;
+ OUString attrName = OUString::createFromAscii(name);
+ if (! me->members->xInvocation->hasMethod (attrName))
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "Attribute " );
+ buf.append( attrName );
+ buf.appendAscii( " unknown" );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ callable = PyUNO_callable_new (
+ me->members->xInvocation,
+ attrName,
+ runtime.getImpl()->cargo->xInvocation,
+ runtime.getImpl()->cargo->xTypeConverter,
+ ACCEPT_UNO_ANY);
+ paras = args;
+ }
+ else
+ {
+ // clean the tuple from uno.Any !
+ int size = PyTuple_Size( args );
+ { // for CC, keeping ref-count of tuple being 1
+ paras = PyRef(PyTuple_New( size ), SAL_NO_ACQUIRE);
+ }
+ for( int i = 0 ; i < size ;i ++ )
+ {
+ PyObject * element = PyTuple_GetItem( args , i );
+ if( PyObject_IsInstance( element , getAnyClass( runtime ).get() ) )
+ {
+ element = PyObject_GetAttrString(
+ element, const_cast< char * >("value") );
+ }
+ else
+ {
+ Py_XINCREF( element );
+ }
+ PyTuple_SetItem( paras.get(), i , element );
+ }
+ callable = PyRef( PyObject_GetAttrString( object , (char*)name ), SAL_NO_ACQUIRE );
+ if( !callable.is() )
+ return 0;
+ }
+ ret = PyRef( PyObject_CallObject( callable.get(), paras.get() ), SAL_NO_ACQUIRE );
+ }
+ catch (::com::sun::star::lang::IllegalArgumentException &e)
+ {
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+ catch (::com::sun::star::script::CannotConvertException &e)
+ {
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+ catch (::com::sun::star::uno::RuntimeException &e)
+ {
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+ catch (::com::sun::star::uno::Exception &e)
+ {
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+
+ return ret.getAcquired();
+}
+
+PyObject *PyUNO_str( PyObject * self )
+{
+ PyUNO *me = ( PyUNO * ) self;
+
+ OStringBuffer buf;
+
+
+ if( me->members->wrappedObject.getValueType().getTypeClass()
+ == com::sun::star::uno::TypeClass_STRUCT ||
+ me->members->wrappedObject.getValueType().getTypeClass()
+ == com::sun::star::uno::TypeClass_EXCEPTION)
+ {
+ Reference< XMaterialHolder > rHolder(me->members->xInvocation,UNO_QUERY);
+ if( rHolder.is() )
+ {
+ PyThreadDetach antiguard;
+ Any a = rHolder->getMaterial();
+ OUString s = val2str( (void*) a.getValue(), a.getValueType().getTypeLibType() );
+ buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
+ }
+ }
+ else
+ {
+ // a common UNO object
+ PyThreadDetach antiguard;
+ buf.append( "pyuno object " );
+
+ OUString s = val2str( (void*)me->members->wrappedObject.getValue(),
+ me->members->wrappedObject.getValueType().getTypeLibType() );
+ buf.append( OUStringToOString(s,RTL_TEXTENCODING_ASCII_US) );
+ }
+
+ return PyString_FromString( buf.getStr());
+}
+
+PyObject* PyUNO_getattr (PyObject* self, char* name)
+{
+ PyUNO* me;
+
+ try
+ {
+
+ Runtime runtime;
+
+ me = (PyUNO*) self;
+ //Handle Python dir () stuff first...
+ if (strcmp (name, "__members__") == 0)
+ {
+ PyObject* member_list;
+ Sequence<OUString> oo_member_list;
+
+ oo_member_list = me->members->xInvocation->getMemberNames ();
+ member_list = PyList_New (oo_member_list.getLength ());
+ for (int i = 0; i < oo_member_list.getLength (); i++)
+ {
+ // setitem steals a reference
+ PyList_SetItem (member_list, i, ustring2PyString(oo_member_list[i]).getAcquired() );
+ }
+ return member_list;
+ }
+
+ if (strcmp (name, "__dict__") == 0)
+ {
+ Py_INCREF (Py_None);
+ return Py_None;
+ }
+ if (strcmp (name, "__methods__") == 0)
+ {
+ Py_INCREF (Py_None);
+ return Py_None;
+ }
+ if (strcmp (name, "__class__") == 0)
+ {
+ if( me->members->wrappedObject.getValueTypeClass() ==
+ com::sun::star::uno::TypeClass_STRUCT ||
+ me->members->wrappedObject.getValueTypeClass() ==
+ com::sun::star::uno::TypeClass_EXCEPTION )
+ {
+ return getClass(
+ me->members->wrappedObject.getValueType().getTypeName(), runtime ).getAcquired();
+ }
+ Py_INCREF (Py_None);
+ return Py_None;
+ }
+
+ OUString attrName( OUString::createFromAscii( name ) );
+ //We need to find out if it's a method...
+ if (me->members->xInvocation->hasMethod (attrName))
+ {
+ //Create a callable object to invoke this...
+ PyRef ret = PyUNO_callable_new (
+ me->members->xInvocation,
+ attrName,
+ runtime.getImpl()->cargo->xInvocation,
+ runtime.getImpl()->cargo->xTypeConverter);
+ Py_XINCREF( ret.get() );
+ return ret.get();
+
+ }
+
+ //or a property
+ if (me->members->xInvocation->hasProperty ( attrName))
+ {
+ //Return the value of the property
+ Any anyRet;
+ {
+ PyThreadDetach antiguard;
+ anyRet = me->members->xInvocation->getValue (attrName);
+ }
+ PyRef ret = runtime.any2PyObject(anyRet);
+ Py_XINCREF( ret.get() );
+ return ret.get();
+ }
+
+ //or else...
+ PyErr_SetString (PyExc_AttributeError, name);
+ }
+ catch( com::sun::star::reflection::InvocationTargetException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e.TargetException) );
+ }
+ catch( com::sun::star::beans::UnknownPropertyException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ catch( com::sun::star::lang::IllegalArgumentException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ catch( com::sun::star::script::CannotConvertException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ catch( RuntimeException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+
+ return NULL;
+}
+
+int PyUNO_setattr (PyObject* self, char* name, PyObject* value)
+{
+ PyUNO* me;
+
+ me = (PyUNO*) self;
+ try
+ {
+ Runtime runtime;
+ Any val= runtime.pyObject2Any(value, ACCEPT_UNO_ANY);
+
+ OUString attrName( OUString::createFromAscii( name ) );
+ {
+ PyThreadDetach antiguard;
+ if (me->members->xInvocation->hasProperty (attrName))
+ {
+ me->members->xInvocation->setValue (attrName, val);
+ return 0; //Keep with Python's boolean system
+ }
+ }
+ }
+ catch( com::sun::star::reflection::InvocationTargetException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e.TargetException) );
+ return 1;
+ }
+ catch( com::sun::star::beans::UnknownPropertyException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ return 1;
+ }
+ catch( com::sun::star::script::CannotConvertException &e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ return 1;
+ }
+ catch( RuntimeException & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ return 1;
+ }
+ PyErr_SetString (PyExc_AttributeError, name);
+ return 1; //as above.
+}
+
+// ensure object identity and struct equality
+static int PyUNO_cmp( PyObject *self, PyObject *that )
+{
+ if( self == that )
+ return 0;
+ int retDefault = self > that ? 1 : -1;
+ try
+ {
+ Runtime runtime;
+ if( PyObject_IsInstance( that, getPyUnoClass( runtime ).get() ) )
+ {
+
+ PyUNO *me = reinterpret_cast< PyUNO*> ( self );
+ PyUNO *other = reinterpret_cast< PyUNO *> (that );
+ com::sun::star::uno::TypeClass tcMe = me->members->wrappedObject.getValueTypeClass();
+ com::sun::star::uno::TypeClass tcOther = other->members->wrappedObject.getValueTypeClass();
+
+ if( tcMe == tcOther )
+ {
+ if( tcMe == com::sun::star::uno::TypeClass_STRUCT ||
+ tcMe == com::sun::star::uno::TypeClass_EXCEPTION )
+ {
+ Reference< XMaterialHolder > xMe( me->members->xInvocation,UNO_QUERY);
+ Reference< XMaterialHolder > xOther( other->members->xInvocation,UNO_QUERY );
+ if( xMe->getMaterial() == xOther->getMaterial() )
+ return 0;
+ }
+ else if( tcMe == com::sun::star::uno::TypeClass_INTERFACE )
+ {
+ if( me->members->wrappedObject == other->members->wrappedObject )
+// if( me->members->xInvocation == other->members->xInvocation )
+ return 0;
+ }
+ }
+ }
+ }
+ catch( com::sun::star::uno::RuntimeException & e)
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ return retDefault;
+}
+
+static PyTypeObject PyUNOType =
+{
+ PyObject_HEAD_INIT (&PyType_Type)
+ 0,
+ const_cast< char * >("pyuno"),
+ sizeof (PyUNO),
+ 0,
+ (destructor) PyUNO_del,
+ (printfunc) 0,
+ (getattrfunc) PyUNO_getattr,
+ (setattrfunc) PyUNO_setattr,
+ (cmpfunc) PyUNO_cmp,
+ (reprfunc) PyUNO_repr,
+ 0,
+ 0,
+ 0,
+ (hashfunc) 0,
+ (ternaryfunc) 0,
+ (reprfunc) PyUNO_str,
+ (getattrofunc)0,
+ (setattrofunc)0,
+ NULL,
+ 0,
+ NULL,
+ (traverseproc)0,
+ (inquiry)0,
+ (richcmpfunc)0,
+ 0,
+ (getiterfunc)0,
+ (iternextfunc)0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (descrgetfunc)0,
+ (descrsetfunc)0,
+ 0,
+ (initproc)0,
+ (allocfunc)0,
+ (newfunc)0,
+ (freefunc)0,
+ (inquiry)0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (destructor)0
+#if PY_VERSION_HEX >= 0x02060000
+ , 0
+#endif
+};
+
+PyRef getPyUnoClass( const Runtime &)
+{
+ return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) );
+}
+
+PyObject* PyUNO_new (
+ const Any & targetInterface, const Reference<XSingleServiceFactory> &ssf)
+{
+ Reference<XInterface> tmp_interface;
+
+ targetInterface >>= tmp_interface;
+ if (!tmp_interface.is ())
+ {
+ // empty reference !
+ Py_INCREF( Py_None );
+ return Py_None;
+ }
+
+ return PyUNO_new_UNCHECKED (targetInterface, ssf);
+}
+
+
+PyObject* PyUNO_new_UNCHECKED (
+ const Any &targetInterface,
+ const Reference<XSingleServiceFactory> &ssf )
+{
+ PyUNO* self;
+ Sequence<Any> arguments (1);
+ Reference<XInterface> tmp_interface;
+
+ self = PyObject_New (PyUNO, &PyUNOType);
+ if (self == NULL)
+ return NULL; //NULL == error
+ self->members = new PyUNOInternals();
+
+ arguments[0] <<= targetInterface;
+ {
+ PyThreadDetach antiguard;
+ tmp_interface = ssf->createInstanceWithArguments (arguments);
+ Reference<XInvocation2> tmp_invocation (tmp_interface, UNO_QUERY);
+ self->members->xInvocation = tmp_invocation;
+ self->members->wrappedObject = targetInterface;
+ }
+ return (PyObject*) self;
+}
+
+}
diff --git a/pyuno/source/module/pyuno.flt b/pyuno/source/module/pyuno.flt
new file mode 100755
index 000000000000..f4b498a6964c
--- /dev/null
+++ b/pyuno/source/module/pyuno.flt
@@ -0,0 +1,14 @@
+??_R0?AVException@uno@star@sun@com@@@8??0Exception@uno@star@sun@com@@QAE@ABV01234@@Z8
+??_R0?AVIllegalArgumentException@lang@star@sun@com@@@8??0IllegalArgumentException@lang@star@sun@com@@QAE@ABV01234@@Z12
+??_R0?AVInvocationTargetException@reflection@star@sun@com@@@8??0InvocationTargetException@reflection@star@sun@com@@QAE@ABV01234@@Z20
+??_R0?AVRuntimeException@uno@star@sun@com@@@8??0RuntimeException@uno@star@sun@com@@QAE@ABV01234@@Z8
+??_R0?AVUnknownPropertyException@beans@star@sun@com@@@8??0UnknownPropertyException@beans@star@sun@com@@QAE@ABV01234@@Z8
+??_R0?AVWrappedTargetException@lang@star@sun@com@@@8??0WrappedTargetException@lang@star@sun@com@@QAE@ABV01234@@Z20
+?AVIllegalArgumentException@lang@star@sun@com@@
+?AVRuntimeException@uno@star@sun@com@@
+?AVUnknownPropertyException@beans@star@sun@com@@
+?AVInvocationTargetException@reflection@star@sun@com@@
+__CT??_R0?AVbad_alloc@std@@@8??0bad_alloc@std@@QAE@ABV01@@Z12
+__CT??_R0?AVexception@@@8??0exception@@QAE@ABV0@@Z12
+__CTA2?AVbad_alloc@std@@
+__CT??
diff --git a/pyuno/source/module/pyuno_adapter.cxx b/pyuno/source/module/pyuno_adapter.cxx
new file mode 100644
index 000000000000..6f2fcdc3dbd5
--- /dev/null
+++ b/pyuno/source/module/pyuno_adapter.cxx
@@ -0,0 +1,437 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "pyuno_impl.hxx"
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <com/sun/star/beans/MethodConcept.hpp>
+
+#include <cppuhelper/typeprovider.hxx>
+
+using rtl::OUStringToOString;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using rtl::OString;
+using rtl::OStringBuffer;
+
+using com::sun::star::beans::XIntrospectionAccess;
+using com::sun::star::beans::XIntrospection;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::makeAny;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Type;
+using com::sun::star::lang::XUnoTunnel;
+using com::sun::star::lang::IllegalArgumentException;
+using com::sun::star::beans::UnknownPropertyException;
+using com::sun::star::script::CannotConvertException;
+using com::sun::star::reflection::InvocationTargetException;
+using com::sun::star::reflection::XIdlMethod;
+using com::sun::star::reflection::ParamInfo;
+using com::sun::star::reflection::XIdlClass;
+
+#define TO_ASCII(x) OUStringToOString( x , RTL_TEXTENCODING_ASCII_US).getStr()
+
+namespace pyuno
+{
+
+Adapter::Adapter( const PyRef & ref, const Sequence< Type > &types )
+ : mWrappedObject( ref ),
+ mInterpreter( (PyThreadState_Get()->interp) ),
+ mTypes( types )
+{}
+
+Adapter::~Adapter()
+{
+ // Problem: We don't know, if we have the python interpreter lock
+ // There is no runtime function to get to know this.
+ decreaseRefCount( mInterpreter, mWrappedObject.get() );
+ mWrappedObject.scratch();
+}
+
+static cppu::OImplementationId g_id( sal_False );
+
+Sequence<sal_Int8> Adapter::getUnoTunnelImplementationId()
+{
+ return g_id.getImplementationId();
+}
+
+sal_Int64 Adapter::getSomething( const Sequence< sal_Int8 > &id) throw (RuntimeException)
+{
+ if( id == g_id.getImplementationId() )
+ return reinterpret_cast<sal_Int64>(this);
+ return 0;
+}
+
+void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
+ throw ( InvocationTargetException )
+{
+ if( PyErr_Occurred() )
+ {
+ PyRef excType, excValue, excTraceback;
+ PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
+ Any unoExc( runtime.extractUnoException( excType, excValue, excTraceback ) );
+ throw InvocationTargetException(
+ ((com::sun::star::uno::Exception*)unoExc.getValue())->Message,
+ Reference<XInterface>(), unoExc );
+ }
+}
+
+Reference< XIntrospectionAccess > Adapter::getIntrospection()
+ throw ( RuntimeException )
+{
+ // not supported
+ return Reference< XIntrospectionAccess > ();
+}
+
+Sequence< sal_Int16 > Adapter::getOutIndexes( const OUString & functionName )
+{
+ Sequence< sal_Int16 > ret;
+ MethodOutIndexMap::const_iterator ii = m_methodOutIndexMap.find( functionName );
+ if( ii == m_methodOutIndexMap.end() )
+ {
+
+ Runtime runtime;
+ {
+ PyThreadDetach antiguard;
+
+ // retrieve the adapter object again. It will be the same instance as before,
+ // (the adapter factory keeps a weak map inside, which I couldn't have outside)
+ Reference< XInterface > unoAdapterObject =
+ runtime.getImpl()->cargo->xAdapterFactory->createAdapter( this, mTypes );
+
+ // uuuh, that's really expensive. The alternative would have been, to store
+ // an instance of the introspection at (this), but this results in a cyclic
+ // reference, which is never broken (as it is up to OOo1.1.0).
+ Reference< XIntrospectionAccess > introspection =
+ runtime.getImpl()->cargo->xIntrospection->inspect( makeAny( unoAdapterObject ) );
+
+ if( !introspection.is() )
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno bridge: Couldn't inspect uno adapter ( the python class must implement com.sun.star.lang.XTypeProvider !)" ) ),
+ Reference< XInterface > () );
+ }
+
+ Reference< XIdlMethod > method = introspection->getMethod(
+ functionName, com::sun::star::beans::MethodConcept::ALL );
+ if( ! method.is( ) )
+ {
+ throw RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "pyuno bridge: Couldn't get reflection for method "))
+ + functionName),
+ Reference< XInterface > () );
+ }
+
+ Sequence< ParamInfo > seqInfo = method->getParameterInfos();
+ int i;
+ int nOuts = 0;
+ for( i = 0 ; i < seqInfo.getLength() ; i ++ )
+ {
+ if( seqInfo[i].aMode == com::sun::star::reflection::ParamMode_OUT ||
+ seqInfo[i].aMode == com::sun::star::reflection::ParamMode_INOUT )
+ {
+ // sequence must be interpreted as return value/outparameter tuple !
+ nOuts ++;
+ }
+ }
+
+ if( nOuts )
+ {
+ ret.realloc( nOuts );
+ sal_Int32 nOutsAssigned = 0;
+ for( i = 0 ; i < seqInfo.getLength() ; i ++ )
+ {
+ if( seqInfo[i].aMode == com::sun::star::reflection::ParamMode_OUT ||
+ seqInfo[i].aMode == com::sun::star::reflection::ParamMode_INOUT )
+ {
+ ret[nOutsAssigned] = (sal_Int16) i;
+ nOutsAssigned ++;
+ }
+ }
+ }
+ }
+ // guard active again !
+ m_methodOutIndexMap[ functionName ] = ret;
+ }
+ else
+ {
+ ret = ii->second;
+ }
+ return ret;
+}
+
+Any Adapter::invoke( const OUString &aFunctionName,
+ const Sequence< Any >& aParams,
+ Sequence< sal_Int16 > &aOutParamIndex,
+ Sequence< Any > &aOutParam)
+ throw (IllegalArgumentException,CannotConvertException,InvocationTargetException,RuntimeException)
+{
+ Any ret;
+
+ // special hack for the uno object identity concept. The XUnoTunnel.getSomething() call is
+ // always handled by the adapter directly.
+ if( aParams.getLength() == 1 && 0 == aFunctionName.compareToAscii( "getSomething" ) )
+ {
+ Sequence< sal_Int8 > id;
+ if( aParams[0] >>= id )
+ return com::sun::star::uno::makeAny( getSomething( id ) );
+
+ }
+
+ RuntimeCargo *cargo = 0;
+ try
+ {
+ PyThreadAttach guard( mInterpreter );
+ {
+ // convert parameters to python args
+ // TODO: Out parameter
+ Runtime runtime;
+ cargo = runtime.getImpl()->cargo;
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logCall( cargo, "try uno->py[0x",
+ mWrappedObject.get(), aFunctionName, aParams );
+ }
+
+ sal_Int32 size = aParams.getLength();
+ PyRef argsTuple(PyTuple_New( size ), SAL_NO_ACQUIRE );
+ int i;
+ // fill tuple with default values in case of exceptions
+ for( i = 0 ;i < size ; i ++ )
+ {
+ Py_INCREF( Py_None );
+ PyTuple_SetItem( argsTuple.get(), i, Py_None );
+ }
+
+ // convert args to python
+ for( i = 0; i < size ; i ++ )
+ {
+ PyRef val = runtime.any2PyObject( aParams[i] );
+ PyTuple_SetItem( argsTuple.get(), i, val.getAcquired() );
+ }
+
+ // get callable
+ PyRef method(PyObject_GetAttrString( mWrappedObject.get(), (char*)TO_ASCII(aFunctionName)),
+ SAL_NO_ACQUIRE);
+ raiseInvocationTargetExceptionWhenNeeded( runtime);
+ if( !method.is() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno::Adapater: Method " ).append( aFunctionName );
+ buf.appendAscii( " is not implemented at object " );
+ PyRef str( PyObject_Repr( mWrappedObject.get() ), SAL_NO_ACQUIRE );
+ buf.appendAscii( PyString_AsString( str.get() ));
+ throw IllegalArgumentException( buf.makeStringAndClear(), Reference< XInterface > (),0 );
+ }
+
+ PyRef pyRet( PyObject_CallObject( method.get(), argsTuple.get() ), SAL_NO_ACQUIRE );
+ raiseInvocationTargetExceptionWhenNeeded( runtime);
+ if( pyRet.is() )
+ {
+ ret = runtime.pyObject2Any( pyRet );
+
+ if( ret.hasValue() &&
+ ret.getValueTypeClass() == com::sun::star::uno::TypeClass_SEQUENCE &&
+ 0 != aFunctionName.compareToAscii( "getTypes" ) && // needed by introspection itself !
+ 0 != aFunctionName.compareToAscii( "getImplementationId" ) ) // needed by introspection itself !
+ {
+ // the sequence can either be
+ // 1) a simple sequence return value
+ // 2) a sequence, where the first element is the return value
+ // and the following elements are interpreted as the outparameter
+ // I can only decide for one solution by checking the method signature,
+ // so I need the reflection of the adapter !
+ aOutParamIndex = getOutIndexes( aFunctionName );
+ if( aOutParamIndex.getLength() )
+ {
+ // out parameters exist, extract the sequence
+ Sequence< Any > seq;
+ if( ! ( ret >>= seq ) )
+ {
+ throw RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "pyuno bridge: Couldn't extract out"
+ " parameters for method "))
+ + aFunctionName),
+ Reference< XInterface > () );
+ }
+
+ if( aOutParamIndex.getLength() +1 != seq.getLength() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno bridge: expected for method " );
+ buf.append( aFunctionName );
+ buf.appendAscii( " one return value and " );
+ buf.append( (sal_Int32) aOutParamIndex.getLength() );
+ buf.appendAscii( " out parameters, got a sequence of " );
+ buf.append( seq.getLength() );
+ buf.appendAscii( " elements as return value." );
+ throw RuntimeException(buf.makeStringAndClear(), *this );
+ }
+
+ aOutParam.realloc( aOutParamIndex.getLength() );
+ ret = seq[0];
+ for( i = 0 ; i < aOutParamIndex.getLength() ; i ++ )
+ {
+ aOutParam[i] = seq[1+i];
+ }
+ }
+ // else { sequence is a return value !}
+ }
+ }
+
+ // log the reply, if desired
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logReply( cargo, "success uno->py[0x" ,
+ mWrappedObject.get(), aFunctionName, ret, aOutParam );
+ }
+ }
+
+ }
+ catch(InvocationTargetException & e )
+ {
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logException(
+ cargo, "except uno->py[0x" ,
+ mWrappedObject.get(), aFunctionName,
+ e.TargetException.getValue(),e.TargetException.getValueType() );
+ }
+ throw;
+ }
+ catch( RuntimeException & e )
+ {
+ if( cargo && isLog( cargo, LogLevel::CALL ) )
+ {
+ logException(
+ cargo, "except uno->py[0x" ,
+ mWrappedObject.get(), aFunctionName, &e,getCppuType(&e) );
+ }
+ throw;
+ }
+ catch( CannotConvertException & e )
+ {
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logException(
+ cargo, "except uno->py[0x" ,
+ mWrappedObject.get(), aFunctionName, &e,getCppuType(&e) );
+ }
+ throw;
+ }
+ catch( IllegalArgumentException & e )
+ {
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logException(
+ cargo, "except uno->py[0x" ,
+ mWrappedObject.get(), aFunctionName, &e,getCppuType(&e) );
+ }
+ throw;
+ }
+ return ret;
+}
+
+void Adapter::setValue( const OUString & aPropertyName, const Any & value )
+ throw( UnknownPropertyException, CannotConvertException, InvocationTargetException,RuntimeException)
+{
+ PyThreadAttach guard( mInterpreter );
+ try
+ {
+ Runtime runtime;
+ PyRef obj = runtime.any2PyObject( value );
+
+ if( !hasProperty( aPropertyName ) )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno::Adapater: Property " ).append( aPropertyName );
+ buf.appendAscii( " is unknown." );
+ throw UnknownPropertyException( buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+
+ PyObject_SetAttrString(
+ mWrappedObject.get(), (char*)TO_ASCII(aPropertyName), obj.get() );
+ raiseInvocationTargetExceptionWhenNeeded( runtime);
+
+ }
+ catch( IllegalArgumentException & exc )
+ {
+ throw InvocationTargetException( exc.Message, *this, com::sun::star::uno::makeAny( exc ) );
+ }
+}
+
+Any Adapter::getValue( const OUString & aPropertyName )
+ throw ( UnknownPropertyException, RuntimeException )
+{
+ Any ret;
+ PyThreadAttach guard( mInterpreter );
+ {
+ Runtime runtime;
+ PyRef pyRef(
+ PyObject_GetAttrString( mWrappedObject.get(), (char*)TO_ASCII(aPropertyName) ),
+ SAL_NO_ACQUIRE );
+
+ raiseInvocationTargetExceptionWhenNeeded( runtime);
+ if( !pyRef.is() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno::Adapater: Property " ).append( aPropertyName );
+ buf.appendAscii( " is unknown." );
+ throw UnknownPropertyException( buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ ret = runtime.pyObject2Any( pyRef );
+ }
+ return ret;
+}
+
+sal_Bool Adapter::hasMethod( const OUString & aMethodName )
+ throw ( RuntimeException )
+{
+ return hasProperty( aMethodName );
+}
+
+sal_Bool Adapter::hasProperty( const OUString & aPropertyName )
+ throw ( RuntimeException )
+{
+ bool bRet = false;
+ PyThreadAttach guard( mInterpreter );
+ {
+ bRet = PyObject_HasAttrString(
+ mWrappedObject.get() , (char*) TO_ASCII( aPropertyName ));
+ }
+ return bRet;
+}
+
+}
diff --git a/pyuno/source/module/pyuno_callable.cxx b/pyuno/source/module/pyuno_callable.cxx
new file mode 100644
index 000000000000..8fff629daa80
--- /dev/null
+++ b/pyuno/source/module/pyuno_callable.cxx
@@ -0,0 +1,273 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "pyuno_impl.hxx"
+
+#include <osl/thread.h>
+#include <rtl/ustrbuf.hxx>
+
+using rtl::OUStringToOString;
+using rtl::OUString;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::Type;
+using com::sun::star::uno::TypeClass;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::XComponentContext;
+using com::sun::star::lang::XSingleServiceFactory;
+using com::sun::star::script::XTypeConverter;
+using com::sun::star::script::XInvocation2;
+
+namespace pyuno
+{
+typedef struct
+{
+ Reference<XInvocation2> xInvocation;
+ Reference<XSingleServiceFactory> xInvocationFactory;
+ Reference<XTypeConverter> xTypeConverter;
+ OUString methodName;
+ ConversionMode mode;
+} PyUNO_callable_Internals;
+
+typedef struct
+{
+ PyObject_HEAD
+ PyUNO_callable_Internals* members;
+} PyUNO_callable;
+
+void PyUNO_callable_del (PyObject* self)
+{
+ PyUNO_callable* me;
+
+ me = (PyUNO_callable*) self;
+ delete me->members;
+ PyObject_Del (self);
+
+ return;
+}
+
+PyObject* PyUNO_callable_call (PyObject* self, PyObject* args, PyObject*)
+{
+ PyUNO_callable* me;
+
+ Sequence<short> aOutParamIndex;
+ Sequence<Any> aOutParam;
+ Sequence<Any> aParams;
+ Sequence<Type> aParamTypes;
+ Any any_params;
+ Any out_params;
+ Any ret_value;
+ RuntimeCargo *cargo = 0;
+ me = (PyUNO_callable*) self;
+
+ PyRef ret;
+ try
+ {
+ Runtime runtime;
+ cargo = runtime.getImpl()->cargo;
+ any_params = runtime.pyObject2Any (args, me->members->mode);
+
+ if (any_params.getValueTypeClass () == com::sun::star::uno::TypeClass_SEQUENCE)
+ {
+ any_params >>= aParams;
+ }
+ else
+ {
+ aParams.realloc (1);
+ aParams [0] <<= any_params;
+ }
+
+ {
+ PyThreadDetach antiguard; //pyhton free zone
+
+ // do some logging if desired ...
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logCall( cargo, "try py->uno[0x", me->members->xInvocation.get(),
+ me->members->methodName, aParams );
+ }
+
+ // do the call
+ ret_value = me->members->xInvocation->invoke (
+ me->members->methodName, aParams, aOutParamIndex, aOutParam);
+
+ // log the reply, if desired
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logReply( cargo, "success py->uno[0x", me->members->xInvocation.get(),
+ me->members->methodName, ret_value, aOutParam);
+ }
+ }
+
+
+ PyRef temp = runtime.any2PyObject (ret_value);
+ if( aOutParam.getLength() )
+ {
+ PyRef return_list( PyTuple_New (1+aOutParam.getLength()), SAL_NO_ACQUIRE );
+ PyTuple_SetItem (return_list.get(), 0, temp.getAcquired());
+
+ // initialize with defaults in case of exceptions
+ int i;
+ for( i = 1 ; i < 1+aOutParam.getLength() ; i ++ )
+ {
+ Py_INCREF( Py_None );
+ PyTuple_SetItem( return_list.get() , i , Py_None );
+ }
+
+ for( i = 0 ; i < aOutParam.getLength() ; i ++ )
+ {
+ PyRef ref = runtime.any2PyObject( aOutParam[i] );
+ PyTuple_SetItem (return_list.get(), 1+i, ref.getAcquired());
+ }
+ ret = return_list;
+ }
+ else
+ {
+ ret = temp;
+ }
+ }
+ catch( com::sun::star::reflection::InvocationTargetException & e )
+ {
+
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logException( cargo, "except py->uno[0x", me->members->xInvocation.get() ,
+ me->members->methodName, e.TargetException.getValue(), e.TargetException.getValueTypeRef());
+ }
+ raisePyExceptionWithAny( e.TargetException );
+ }
+ catch( com::sun::star::script::CannotConvertException &e )
+ {
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
+ me->members->methodName, &e, getCppuType(&e).getTypeLibType());
+ }
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+ catch( com::sun::star::lang::IllegalArgumentException &e )
+ {
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
+ me->members->methodName, &e, getCppuType(&e).getTypeLibType());
+ }
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+ catch (::com::sun::star::uno::RuntimeException &e)
+ {
+ if( cargo && isLog( cargo, LogLevel::CALL ) )
+ {
+ logException( cargo, "error py->uno[0x", me->members->xInvocation.get() ,
+ me->members->methodName, &e, getCppuType(&e).getTypeLibType());
+ }
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+
+ return ret.getAcquired();
+}
+
+
+static PyTypeObject PyUNO_callable_Type =
+{
+ PyObject_HEAD_INIT (&PyType_Type)
+ 0,
+ const_cast< char * >("PyUNO_callable"),
+ sizeof (PyUNO_callable),
+ 0,
+ (destructor) ::pyuno::PyUNO_callable_del,
+ (printfunc) 0,
+ (getattrfunc) 0,
+ (setattrfunc) 0,
+ (cmpfunc) 0,
+ (reprfunc) 0,
+ 0,
+ 0,
+ 0,
+ (hashfunc) 0,
+ (ternaryfunc) ::pyuno::PyUNO_callable_call,
+ (reprfunc) 0,
+ (getattrofunc)0,
+ (setattrofunc)0,
+ NULL,
+ 0,
+ NULL,
+ (traverseproc)0,
+ (inquiry)0,
+ (richcmpfunc)0,
+ 0,
+ (getiterfunc)0,
+ (iternextfunc)0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (descrgetfunc)0,
+ (descrsetfunc)0,
+ 0,
+ (initproc)0,
+ (allocfunc)0,
+ (newfunc)0,
+ (freefunc)0,
+ (inquiry)0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (destructor)0
+#if PY_VERSION_HEX >= 0x02060000
+ , 0
+#endif
+};
+
+PyRef PyUNO_callable_new (
+ const Reference<XInvocation2> &my_inv,
+ const OUString & methodName,
+ const Reference<XSingleServiceFactory> &xInvocationFactory,
+ const Reference<XTypeConverter> &tc,
+ enum ConversionMode mode )
+{
+ PyUNO_callable* self;
+
+ self = PyObject_New (PyUNO_callable, &PyUNO_callable_Type);
+ if (self == NULL)
+ return NULL; //NULL == Error!
+
+ self->members = new PyUNO_callable_Internals;
+ self->members->xInvocation = my_inv;
+ self->members->methodName = methodName;
+ self->members->xInvocationFactory = xInvocationFactory;
+ self->members->xTypeConverter = tc;
+ self->members->mode = mode;
+
+ return PyRef( (PyObject*)self, SAL_NO_ACQUIRE );
+}
+
+}
diff --git a/pyuno/source/module/pyuno_dlopenwrapper.c b/pyuno/source/module/pyuno_dlopenwrapper.c
new file mode 100644
index 000000000000..517d4f86cd2f
--- /dev/null
+++ b/pyuno/source/module/pyuno_dlopenwrapper.c
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <rtl/string.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef LINUX
+# ifndef __USE_GNU
+# define __USE_GNU
+# endif
+#endif
+#include <dlfcn.h>
+
+void initpyuno ()
+{
+ Dl_info dl_info;
+ void (*func)(void);
+
+ if (dladdr((void*)&initpyuno, &dl_info) != 0) {
+ void* h = 0;
+ size_t len = strrchr(dl_info.dli_fname, '/') - dl_info.dli_fname + 1;
+ char* libname = malloc(len + RTL_CONSTASCII_LENGTH( SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION ) + 1);
+ strncpy(libname, dl_info.dli_fname, len);
+ strcpy(libname + (len), SAL_DLLPREFIX "pyuno" SAL_DLLEXTENSION);
+
+ h = dlopen (libname, RTLD_NOW | RTLD_GLOBAL);
+ free(libname);
+ if( h )
+ {
+ func = (void (*)())dlsym (h, "initpyuno");
+ (func) ();
+ }
+ }
+}
diff --git a/pyuno/source/module/pyuno_except.cxx b/pyuno/source/module/pyuno_except.cxx
new file mode 100644
index 000000000000..ba86014b8410
--- /dev/null
+++ b/pyuno/source/module/pyuno_except.cxx
@@ -0,0 +1,251 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "pyuno_impl.hxx"
+
+#include <rtl/ustrbuf.hxx>
+
+#include <typelib/typedescription.hxx>
+
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using rtl::OUStringToOString;
+
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Type;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::TypeDescription;
+
+namespace pyuno
+{
+
+void raisePyExceptionWithAny( const com::sun::star::uno::Any &anyExc )
+{
+ try
+ {
+ Runtime runtime;
+ PyRef exc = runtime.any2PyObject( anyExc );
+ if( exc.is() )
+ {
+ PyRef type( getClass( anyExc.getValueType().getTypeName(),runtime ) );
+ PyErr_SetObject( type.get(), exc.get());
+ }
+ else
+ {
+ com::sun::star::uno::Exception e;
+ anyExc >>= e;
+
+ OUStringBuffer buf;
+ buf.appendAscii( "Couldn't convert uno exception to a python exception (" );
+ buf.append(anyExc.getValueType().getTypeName());
+ buf.appendAscii( ": " );
+ buf.append(e.Message );
+ buf.appendAscii( ")" );
+ PyErr_SetString(
+ PyExc_SystemError,
+ OUStringToOString(buf.makeStringAndClear(),RTL_TEXTENCODING_ASCII_US) );
+ }
+ }
+ catch( com::sun::star::lang::IllegalArgumentException & e)
+ {
+ PyErr_SetString( PyExc_SystemError,
+ OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) );
+ }
+ catch( com::sun::star::script::CannotConvertException & e)
+ {
+ PyErr_SetString( PyExc_SystemError,
+ OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) );
+ }
+ catch( RuntimeException & e)
+ {
+ PyErr_SetString( PyExc_SystemError,
+ OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US) );
+ }
+}
+
+
+static PyRef createClass( const OUString & name, const Runtime &runtime )
+ throw ( RuntimeException )
+{
+ // assuming that this is never deleted !
+ // note I don't have the knowledge how to initialize these type objects correctly !
+ TypeDescription desc( name );
+ if( ! desc.is() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno.getClass: uno exception " );
+ buf.append(name).appendAscii( " is unknown" );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+
+ sal_Bool isStruct = desc.get()->eTypeClass == typelib_TypeClass_STRUCT;
+ sal_Bool isExc = desc.get()->eTypeClass == typelib_TypeClass_EXCEPTION;
+ sal_Bool isInterface = desc.get()->eTypeClass == typelib_TypeClass_INTERFACE;
+ if( !isStruct && !isExc && ! isInterface )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno.getClass: " ).append(name).appendAscii( "is a " );
+ buf.appendAscii(
+ typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass));
+ buf.appendAscii( ", expected EXCEPTION, STRUCT or INTERFACE" );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface>() );
+ }
+
+ // retrieve base class
+ PyRef base;
+ if( isInterface )
+ {
+ typelib_InterfaceTypeDescription *pDesc = (typelib_InterfaceTypeDescription * )desc.get();
+ if( pDesc->pBaseTypeDescription )
+ {
+ base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime );
+ }
+ else
+ {
+ // must be XInterface !
+ }
+ }
+ else
+ {
+ typelib_CompoundTypeDescription *pDesc = (typelib_CompoundTypeDescription*)desc.get();
+ if( pDesc->pBaseTypeDescription )
+ {
+ base = getClass( pDesc->pBaseTypeDescription->aBase.pTypeName, runtime );
+ }
+ else
+ {
+ if( isExc )
+ // we are currently creating the root UNO exception
+ base = PyRef(PyExc_Exception);
+ }
+ }
+ PyRef args( PyTuple_New( 3 ), SAL_NO_ACQUIRE );
+
+ PyRef pyTypeName = ustring2PyString( name /*.replace( '.', '_' )*/ );
+
+ PyRef bases;
+ if( base.is() )
+ {
+ { // for CC, keeping ref-count being 1
+ bases = PyRef( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
+ }
+ PyTuple_SetItem( bases.get(), 0 , base.getAcquired() );
+ }
+ else
+ {
+ bases = PyRef( PyTuple_New( 0 ), SAL_NO_ACQUIRE );
+ }
+
+ PyTuple_SetItem( args.get(), 0, pyTypeName.getAcquired());
+ PyTuple_SetItem( args.get(), 1, bases.getAcquired() );
+ PyTuple_SetItem( args.get(), 2, PyDict_New() );
+
+ PyRef ret(
+ PyObject_CallObject(reinterpret_cast<PyObject *>(&PyClass_Type) , args.get()),
+ SAL_NO_ACQUIRE );
+
+ // now overwrite ctor and attrib functions
+ if( isInterface )
+ {
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__pyunointerface__"),
+ ustring2PyString(name).get() );
+ }
+ else
+ {
+ PyRef ctor = getObjectFromUnoModule( runtime,"_uno_struct__init__" );
+ PyRef setter = getObjectFromUnoModule( runtime,"_uno_struct__setattr__" );
+ PyRef getter = getObjectFromUnoModule( runtime,"_uno_struct__getattr__" );
+ PyRef repr = getObjectFromUnoModule( runtime,"_uno_struct__repr__" );
+ PyRef eq = getObjectFromUnoModule( runtime,"_uno_struct__eq__" );
+
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__pyunostruct__"),
+ ustring2PyString(name).get() );
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("typeName"),
+ ustring2PyString(name).get() );
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__init__"), ctor.get() );
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__getattr__"), getter.get() );
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__setattr__"), setter.get() );
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__repr__"), repr.get() );
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__str__"), repr.get() );
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__eq__"), eq.get() );
+ }
+ return ret;
+}
+
+bool isInstanceOfStructOrException( PyObject *obj)
+{
+ PyRef attr(
+ PyObject_GetAttrString(obj, const_cast< char * >("__class__")),
+ SAL_NO_ACQUIRE );
+ return PyObject_HasAttrString(
+ attr.get(), const_cast< char * >("__pyunostruct__"));
+}
+
+sal_Bool isInterfaceClass( const Runtime &runtime, PyObject * obj )
+{
+ const ClassSet & set = runtime.getImpl()->cargo->interfaceSet;
+ return set.find( obj ) != set.end();
+}
+
+PyRef getClass( const OUString & name , const Runtime &runtime)
+{
+ PyRef ret;
+
+ RuntimeCargo *cargo =runtime.getImpl()->cargo;
+ ExceptionClassMap::iterator ii = cargo->exceptionMap.find( name );
+ if( ii == cargo->exceptionMap.end() )
+ {
+ ret = createClass( name, runtime );
+ cargo->exceptionMap[name] = ret;
+ if( PyObject_HasAttrString(
+ ret.get(), const_cast< char * >("__pyunointerface__") ) )
+ cargo->interfaceSet.insert( ret );
+
+ PyObject_SetAttrString(
+ ret.get(), const_cast< char * >("__pyunointerface__"),
+ ustring2PyString(name).get() );
+ }
+ else
+ {
+ ret = ii->second;
+ }
+
+ return ret;
+}
+
+
+}
diff --git a/pyuno/source/module/pyuno_gc.cxx b/pyuno/source/module/pyuno_gc.cxx
new file mode 100644
index 000000000000..aafefd368a4f
--- /dev/null
+++ b/pyuno/source/module/pyuno_gc.cxx
@@ -0,0 +1,117 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <pyuno_impl.hxx>
+#include <osl/thread.hxx>
+namespace pyuno
+{
+
+bool g_destructorsOfStaticObjectsHaveBeenCalled;
+class StaticDestructorGuard
+{
+public:
+ ~StaticDestructorGuard()
+ {
+ g_destructorsOfStaticObjectsHaveBeenCalled = true;
+ }
+};
+StaticDestructorGuard guard;
+
+static bool isAfterUnloadOrPy_Finalize()
+{
+ return g_destructorsOfStaticObjectsHaveBeenCalled ||
+ !Py_IsInitialized();
+}
+
+class GCThread : public ::osl::Thread
+{
+ PyObject *mPyObject;
+ PyInterpreterState *mPyInterpreter;
+ GCThread( const GCThread & ); // not implemented
+ GCThread &operator =( const GCThread & ); // not implemented
+
+public:
+ GCThread( PyInterpreterState *interpreter, PyObject * object );
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+};
+
+
+GCThread::GCThread( PyInterpreterState *interpreter, PyObject * object ) :
+ mPyObject( object ), mPyInterpreter( interpreter )
+{}
+
+void GCThread::run()
+{
+ // otherwise we crash here, when main has been left already
+ if( isAfterUnloadOrPy_Finalize() )
+ return;
+ try
+ {
+ PyThreadAttach g( (PyInterpreterState*)mPyInterpreter );
+ {
+ Runtime runtime;
+
+ // remove the reference from the pythonobject2adapter map
+ PyRef2Adapter::iterator ii =
+ runtime.getImpl()->cargo->mappedObjects.find( mPyObject );
+ if( ii != runtime.getImpl()->cargo->mappedObjects.end() )
+ {
+ runtime.getImpl()->cargo->mappedObjects.erase( ii );
+ }
+
+ Py_XDECREF( mPyObject );
+ }
+ }
+ catch( com::sun::star::uno::RuntimeException & e )
+ {
+ rtl::OString msg;
+ msg = rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US );
+ fprintf( stderr, "Leaking python objects bridged to UNO for reason %s\n",msg.getStr());
+ }
+}
+
+
+void GCThread::onTerminated()
+{
+ delete this;
+}
+
+void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object )
+{
+ // otherwise we crash in the last after main ...
+ if( isAfterUnloadOrPy_Finalize() )
+ return;
+
+ // delegate to a new thread, because there does not seem
+ // to be a method, which tells, whether the global
+ // interpreter lock is held or not
+ // TODO: Look for a more efficient solution
+ osl::Thread *t = new GCThread( interpreter, object );
+ t->create();
+}
+
+}
diff --git a/pyuno/source/module/pyuno_impl.hxx b/pyuno/source/module/pyuno_impl.hxx
new file mode 100644
index 000000000000..ccb16c24d2a4
--- /dev/null
+++ b/pyuno/source/module/pyuno_impl.hxx
@@ -0,0 +1,293 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _PYUNO_IMPL_
+#define _PYUNO_IMPL_
+
+#include <pyuno/pyuno.hxx>
+
+#include <hash_map>
+#include <hash_set>
+
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/XInvocation2.hpp>
+#include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
+
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/weakref.hxx>
+
+namespace pyuno
+{
+
+//--------------------------------------------------
+// Logging API - implementation can be found in pyuno_util
+//--------------------------------------------------
+struct RuntimeCargo;
+namespace LogLevel
+{
+// when you add a loglevel, extend the log function !
+static const sal_Int32 NONE = 0;
+static const sal_Int32 CALL = 1;
+static const sal_Int32 ARGS = 2;
+}
+
+bool isLog( RuntimeCargo *cargo, sal_Int32 loglevel );
+void log( RuntimeCargo *cargo, sal_Int32 level, const rtl::OUString &logString );
+void log( RuntimeCargo *cargo, sal_Int32 level, const char *str );
+void logCall( RuntimeCargo *cargo, const char *intro,
+ void * ptr, const rtl::OUString & aFunctionName,
+ const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
+void logReply( RuntimeCargo *cargo, const char *intro,
+ void * ptr, const rtl::OUString & aFunctionName,
+ const com::sun::star::uno::Any &returnValue,
+ const com::sun::star::uno::Sequence< com::sun::star::uno::Any > & args );
+void logException( RuntimeCargo *cargo, const char *intro,
+ void * ptr, const rtl::OUString &aFunctionName,
+ const void * data, const com::sun::star::uno::Type & type );
+static const sal_Int32 VAL2STR_MODE_DEEP = 0;
+static const sal_Int32 VAL2STR_MODE_SHALLOW = 1;
+rtl::OUString val2str( const void * pVal, typelib_TypeDescriptionReference * pTypeRef, sal_Int32 mode = VAL2STR_MODE_DEEP ) SAL_THROW( () );
+//--------------------------------------------------
+
+typedef ::std::hash_map
+<
+ PyRef,
+ com::sun::star::uno::WeakReference< com::sun::star::script::XInvocation >,
+ PyRef::Hash,
+ std::equal_to< PyRef >
+> PyRef2Adapter;
+
+
+typedef ::std::hash_map
+<
+rtl::OUString,
+PyRef,
+rtl::OUStringHash,
+std::equal_to<rtl::OUString>
+> ExceptionClassMap;
+
+typedef ::std::hash_map
+<
+ rtl::OUString,
+ com::sun::star::uno::Sequence< sal_Int16 >,
+ rtl::OUStringHash,
+ std::equal_to< rtl::OUString >
+> MethodOutIndexMap;
+
+typedef ::std::hash_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;
+
+PyObject* PyUNO_new(
+ const com::sun::star::uno::Any & targetInterface,
+ const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
+
+PyObject* PyUNO_new_UNCHECKED (
+ const com::sun::star::uno::Any & targetInterface,
+ const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);
+
+typedef struct
+{
+ com::sun::star::uno::Reference <com::sun::star::script::XInvocation2> xInvocation;
+ com::sun::star::uno::Any wrappedObject;
+} PyUNOInternals;
+
+typedef struct
+{
+ PyObject_HEAD
+ PyUNOInternals* members;
+} PyUNO;
+
+PyRef ustring2PyUnicode( const rtl::OUString &source );
+PyRef ustring2PyString( const ::rtl::OUString & source );
+rtl::OUString pyString2ustring( PyObject *str );
+
+
+PyRef AnyToPyObject (const com::sun::star::uno::Any & a, const Runtime &r )
+ throw ( com::sun::star::uno::RuntimeException );
+
+com::sun::star::uno::Any PyObjectToAny (PyObject* o)
+ throw ( com::sun::star::uno::RuntimeException );
+
+void raiseInvocationTargetExceptionWhenNeeded( const Runtime &runtime )
+ throw ( com::sun::star::reflection::InvocationTargetException );
+
+// bool CheckPyObjectTypes (PyObject* o, Sequence<Type> types);
+// bool CheckPyObjectType (PyObject* o, Type type); //Only check 1 object.
+
+com::sun::star::uno::TypeClass StringToTypeClass (char* string);
+
+PyRef PyUNO_callable_new (
+ const com::sun::star::uno::Reference<com::sun::star::script::XInvocation2> &xInv,
+ const rtl::OUString &methodName,
+ const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> &ssf,
+ const com::sun::star::uno::Reference<com::sun::star::script::XTypeConverter> &tc,
+ ConversionMode mode = REJECT_UNO_ANY );
+
+PyObject* PyUNO_Type_new (const char *typeName , com::sun::star::uno::TypeClass t , const Runtime &r );
+PyObject* PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r );
+PyObject* PyUNO_char_new (sal_Unicode c , const Runtime &r);
+PyObject *PyUNO_ByteSequence_new( const com::sun::star::uno::Sequence< sal_Int8 > &, const Runtime &r );
+
+PyObject *importToGlobal( PyObject *typeName, PyObject *dict, PyObject *targetName );
+
+PyRef getTypeClass( const Runtime &);
+PyRef getEnumClass( const Runtime &);
+PyRef getBoolClass( const Runtime &);
+PyRef getCharClass( const Runtime &);
+PyRef getByteSequenceClass( const Runtime & );
+PyRef getPyUnoClass( const Runtime &);
+PyRef getClass( const rtl::OUString & name , const Runtime & runtime );
+PyRef getAnyClass( const Runtime &);
+PyObject *PyUNO_invoke( PyObject *object, const char *name , PyObject *args );
+
+com::sun::star::uno::Any PyEnum2Enum( PyObject *obj )
+ throw ( com::sun::star::uno::RuntimeException );
+sal_Bool PyBool2Bool( PyObject *o, const Runtime & r )
+ throw ( com::sun::star::uno::RuntimeException );
+sal_Unicode PyChar2Unicode( PyObject *o )
+ throw ( com::sun::star::uno::RuntimeException );
+com::sun::star::uno::Type PyType2Type( PyObject * o )
+ throw( com::sun::star::uno::RuntimeException );
+
+void raisePyExceptionWithAny( const com::sun::star::uno::Any &a );
+const char *typeClassToString( com::sun::star::uno::TypeClass t );
+
+PyRef getObjectFromUnoModule( const Runtime &runtime, const char * object )
+ throw ( com::sun::star::uno::RuntimeException );
+
+sal_Bool isInterfaceClass( const Runtime &, PyObject *obj );
+bool isInstanceOfStructOrException( PyObject *obj);
+com::sun::star::uno::Sequence<com::sun::star::uno::Type> implementsInterfaces(
+ const Runtime & runtime, PyObject *obj );
+
+struct RuntimeCargo
+{
+ com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > xInvocation;
+ com::sun::star::uno::Reference< com::sun::star::script::XTypeConverter> xTypeConverter;
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext;
+ com::sun::star::uno::Reference< com::sun::star::reflection::XIdlReflection > xCoreReflection;
+ com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > xTdMgr;
+ com::sun::star::uno::Reference< com::sun::star::script::XInvocationAdapterFactory2 > xAdapterFactory;
+ com::sun::star::uno::Reference< com::sun::star::beans::XIntrospection > xIntrospection;
+ PyRef dictUnoModule;
+ bool valid;
+ ExceptionClassMap exceptionMap;
+ ClassSet interfaceSet;
+ PyRef2Adapter mappedObjects;
+ FILE *logFile;
+ sal_Int32 logLevel;
+
+ PyRef getUnoModule();
+};
+
+struct stRuntimeImpl
+{
+ PyObject_HEAD
+ struct RuntimeCargo *cargo;
+public:
+ static void del( PyObject *self );
+
+ static PyRef create(
+ const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & xContext )
+ throw ( com::sun::star::uno::RuntimeException );
+};
+
+
+class Adapter : public cppu::WeakImplHelper2<
+ com::sun::star::script::XInvocation, com::sun::star::lang::XUnoTunnel >
+{
+ PyRef mWrappedObject;
+ PyInterpreterState *mInterpreter; // interpreters don't seem to be refcounted !
+ com::sun::star::uno::Sequence< com::sun::star::uno::Type > mTypes;
+ MethodOutIndexMap m_methodOutIndexMap;
+
+private:
+ com::sun::star::uno::Sequence< sal_Int16 > getOutIndexes( const rtl::OUString & functionName );
+
+public:
+public:
+ Adapter( const PyRef &obj,
+ const com::sun::star::uno::Sequence< com::sun::star::uno::Type > & types );
+
+ static com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelImplementationId();
+ PyRef getWrappedObject() { return mWrappedObject; }
+ com::sun::star::uno::Sequence< com::sun::star::uno::Type > getWrappedTypes() { return mTypes; }
+ virtual ~Adapter();
+
+ // XInvocation
+ virtual com::sun::star::uno::Reference< ::com::sun::star::beans::XIntrospectionAccess >
+ SAL_CALL getIntrospection( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Any SAL_CALL invoke(
+ const ::rtl::OUString& aFunctionName,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aParams,
+ ::com::sun::star::uno::Sequence< sal_Int16 >& aOutParamIndex,
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aOutParam )
+ throw (::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::script::CannotConvertException,
+ ::com::sun::star::reflection::InvocationTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL setValue(
+ const ::rtl::OUString& aPropertyName,
+ const ::com::sun::star::uno::Any& aValue )
+ throw (::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::script::CannotConvertException,
+ ::com::sun::star::reflection::InvocationTargetException,
+ ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getValue( const ::rtl::OUString& aPropertyName )
+ throw (::com::sun::star::beans::UnknownPropertyException,
+ ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasMethod( const ::rtl::OUString& aName )
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething(
+ const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier )
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+
+/** releases a refcount on the interpreter object and on another given python object.
+
+ The function can be called from any thread regardless of whether the global
+ interpreter lock is held.
+
+ */
+void decreaseRefCount( PyInterpreterState *interpreter, PyObject *object );
+
+}
+
+#endif
diff --git a/pyuno/source/module/pyuno_module.cxx b/pyuno/source/module/pyuno_module.cxx
new file mode 100644
index 000000000000..5f3fc3d054e5
--- /dev/null
+++ b/pyuno/source/module/pyuno_module.cxx
@@ -0,0 +1,717 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "pyuno_impl.hxx"
+
+#include <osl/module.hxx>
+#include <osl/thread.h>
+#include <osl/file.hxx>
+
+#include <typelib/typedescription.hxx>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/uuid.h>
+#include <rtl/bootstrap.hxx>
+
+#include <uno/current_context.hxx>
+#include <cppuhelper/bootstrap.hxx>
+
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#include <com/sun/star/registry/InvalidRegistryException.hpp>
+
+using osl::Module;
+
+using rtl::OString;
+using rtl::OUString;
+using rtl::OUStringToOString;
+using rtl::OUStringBuffer;
+using rtl::OStringBuffer;
+
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::makeAny;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::TypeDescription;
+using com::sun::star::uno::XComponentContext;
+using com::sun::star::container::NoSuchElementException;
+using com::sun::star::reflection::XIdlReflection;
+using com::sun::star::reflection::XIdlClass;
+using com::sun::star::script::XInvocation2;
+
+using namespace pyuno;
+
+namespace {
+
+/**
+ @ index of the next to be used member in the initializer list !
+ */
+sal_Int32 fillStructWithInitializer(
+ const Reference< XInvocation2 > &inv,
+ typelib_CompoundTypeDescription *pCompType,
+ PyObject *initializer,
+ const Runtime &runtime) throw ( RuntimeException )
+{
+ sal_Int32 nIndex = 0;
+ if( pCompType->pBaseTypeDescription )
+ nIndex = fillStructWithInitializer(
+ inv, pCompType->pBaseTypeDescription, initializer, runtime );
+
+ sal_Int32 nTupleSize = PyTuple_Size(initializer);
+ int i;
+ for( i = 0 ; i < pCompType->nMembers ; i ++ )
+ {
+ if( i + nIndex >= nTupleSize )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno._createUnoStructHelper: too few elements in the initializer tuple,");
+ buf.appendAscii( "expected at least " ).append( nIndex + pCompType->nMembers );
+ buf.appendAscii( ", got " ).append( nTupleSize );
+ throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > ());
+ }
+ PyObject *element = PyTuple_GetItem( initializer, i + nIndex );
+ Any a = runtime.pyObject2Any( element, ACCEPT_UNO_ANY );
+ inv->setValue( pCompType->ppMemberNames[i], a );
+ }
+ return i+nIndex;
+}
+
+OUString getLibDir()
+{
+ static OUString *pLibDir;
+ if( !pLibDir )
+ {
+ osl::MutexGuard guard( osl::Mutex::getGlobalMutex() );
+ if( ! pLibDir )
+ {
+ static OUString libDir;
+
+ // workarounds the $(ORIGIN) until it is available
+ if( Module::getUrlFromAddress(
+ reinterpret_cast< oslGenericFunction >(getLibDir), libDir ) )
+ {
+ libDir = OUString( libDir.getStr(), libDir.lastIndexOf('/' ) );
+ OUString name ( RTL_CONSTASCII_USTRINGPARAM( "PYUNOLIBDIR" ) );
+ rtl_bootstrap_set( name.pData, libDir.pData );
+ }
+ pLibDir = &libDir;
+ }
+ }
+ return *pLibDir;
+}
+
+void raisePySystemException( const char * exceptionType, const OUString & message )
+{
+ OStringBuffer buf;
+ buf.append( "Error during bootstrapping uno (");
+ buf.append( exceptionType );
+ buf.append( "):" );
+ buf.append( OUStringToOString( message, osl_getThreadTextEncoding() ) );
+ PyErr_SetString( PyExc_SystemError, buf.makeStringAndClear().getStr() );
+}
+
+extern "C" {
+
+static PyObject* getComponentContext (PyObject*, PyObject*)
+{
+ PyRef ret;
+ try
+ {
+ Reference<XComponentContext> ctx;
+
+ // getLibDir() must be called in order to set bootstrap variables correctly !
+ OUString path( getLibDir());
+ if( Runtime::isInitialized() )
+ {
+ Runtime runtime;
+ ctx = runtime.getImpl()->cargo->xContext;
+ }
+ else
+ {
+ OUString iniFile;
+ if( !path.getLength() )
+ {
+ PyErr_SetString(
+ PyExc_RuntimeError, "osl_getUrlFromAddress fails, that's why I cannot find ini "
+ "file for bootstrapping python uno bridge\n" );
+ return NULL;
+ }
+
+ OUStringBuffer iniFileName;
+ iniFileName.append( path );
+ iniFileName.appendAscii( "/" );
+ iniFileName.appendAscii( SAL_CONFIGFILE( "pyuno" ) );
+ iniFile = iniFileName.makeStringAndClear();
+ osl::DirectoryItem item;
+ if( osl::DirectoryItem::get( iniFile, item ) == item.E_None )
+ {
+ // in case pyuno.ini exists, use this file for bootstrapping
+ PyThreadDetach antiguard;
+ ctx = cppu::defaultBootstrap_InitialComponentContext (iniFile);
+ }
+ else
+ {
+ // defaulting to the standard bootstrapping
+ PyThreadDetach antiguard;
+ ctx = cppu::defaultBootstrap_InitialComponentContext ();
+ }
+
+ }
+
+ if( ! Runtime::isInitialized() )
+ {
+ Runtime::initialize( ctx );
+ }
+ Runtime runtime;
+ ret = runtime.any2PyObject( makeAny( ctx ) );
+ }
+ catch (com::sun::star::registry::InvalidRegistryException &e)
+ {
+ // can't use raisePyExceptionWithAny() here, because the function
+ // does any conversions, which will not work with a
+ // wrongly bootstrapped pyuno!
+ raisePySystemException( "InvalidRegistryException", e.Message );
+ }
+ catch( com::sun::star::lang::IllegalArgumentException & e)
+ {
+ raisePySystemException( "IllegalArgumentException", e.Message );
+ }
+ catch( com::sun::star::script::CannotConvertException & e)
+ {
+ raisePySystemException( "CannotConvertException", e.Message );
+ }
+ catch (com::sun::star::uno::RuntimeException & e)
+ {
+ raisePySystemException( "RuntimeException", e.Message );
+ }
+ catch (com::sun::star::uno::Exception & e)
+ {
+ raisePySystemException( "uno::Exception", e.Message );
+ }
+ return ret.getAcquired();
+}
+
+PyObject * extractOneStringArg( PyObject *args, char const *funcName )
+{
+ if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
+ {
+ OStringBuffer buf;
+ buf.append( funcName ).append( ": expecting one string argument" );
+ PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
+ return NULL;
+ }
+ PyObject *obj = PyTuple_GetItem( args, 0 );
+ if( !PyString_Check( obj ) && ! PyUnicode_Check(obj))
+ {
+ OStringBuffer buf;
+ buf.append( funcName ).append( ": expecting one string argument" );
+ PyErr_SetString( PyExc_TypeError, buf.getStr());
+ return NULL;
+ }
+ return obj;
+}
+
+static PyObject *createUnoStructHelper(PyObject *, PyObject* args )
+{
+ Any IdlStruct;
+ PyRef ret;
+
+ try
+ {
+ Runtime runtime;
+ if( PyTuple_Size( args ) == 2 )
+ {
+ PyObject *structName = PyTuple_GetItem( args,0 );
+ PyObject *initializer = PyTuple_GetItem( args ,1 );
+
+ if( PyString_Check( structName ) )
+ {
+ if( PyTuple_Check( initializer ) )
+ {
+ OUString typeName( OUString::createFromAscii(PyString_AsString(structName)));
+ RuntimeCargo *c = runtime.getImpl()->cargo;
+ Reference<XIdlClass> idl_class ( c->xCoreReflection->forName (typeName),UNO_QUERY);
+ if (idl_class.is ())
+ {
+ idl_class->createObject (IdlStruct);
+ PyUNO *me = (PyUNO*)PyUNO_new_UNCHECKED( IdlStruct, c->xInvocation );
+ PyRef returnCandidate( (PyObject*)me, SAL_NO_ACQUIRE );
+ if( PyTuple_Size( initializer ) > 0 )
+ {
+ TypeDescription desc( typeName );
+ OSL_ASSERT( desc.is() ); // could already instantiate an XInvocation2 !
+
+ typelib_CompoundTypeDescription *pCompType =
+ ( typelib_CompoundTypeDescription * ) desc.get();
+ sal_Int32 n = fillStructWithInitializer(
+ me->members->xInvocation, pCompType, initializer, runtime );
+ if( n != PyTuple_Size(initializer) )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno._createUnoStructHelper: wrong number of ");
+ buf.appendAscii( "elements in the initializer list, expected " );
+ buf.append( n );
+ buf.appendAscii( ", got " );
+ buf.append( (sal_Int32) PyTuple_Size(initializer) );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface > ());
+ }
+ }
+ ret = returnCandidate;
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "UNO struct " );
+ buf.append( PyString_AsString(structName) );
+ buf.append( " is unkown" );
+ PyErr_SetString (PyExc_RuntimeError, buf.getStr());
+ }
+ }
+ else
+ {
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ "pyuno._createUnoStructHelper: 2nd argument (initializer sequence) is no tuple" );
+ }
+ }
+ else
+ {
+ PyErr_SetString (PyExc_AttributeError, "createUnoStruct: first argument wasn't a string");
+ }
+ }
+ else
+ {
+ PyErr_SetString (PyExc_AttributeError, "1 Arguments: Structure Name");
+ }
+ }
+ catch( com::sun::star::uno::RuntimeException & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ catch( com::sun::star::script::CannotConvertException & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ catch( com::sun::star::uno::Exception & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ return ret.getAcquired();
+}
+
+static PyObject *getTypeByName( PyObject *, PyObject *args )
+{
+ PyObject * ret = NULL;
+
+ try
+ {
+ char *name;
+
+ if (PyArg_ParseTuple (args, const_cast< char * >("s"), &name))
+ {
+ OUString typeName ( OUString::createFromAscii( name ) );
+ TypeDescription typeDesc( typeName );
+ if( typeDesc.is() )
+ {
+ Runtime runtime;
+ ret = PyUNO_Type_new(
+ name, (com::sun::star::uno::TypeClass)typeDesc.get()->eTypeClass, runtime );
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "Type " ).append(name).append( " is unknown" );
+ PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
+ }
+ }
+ }
+ catch ( RuntimeException & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ return ret;
+}
+
+static PyObject *getConstantByName( PyObject *, PyObject *args )
+{
+ PyObject *ret = 0;
+ try
+ {
+ char *name;
+
+ if (PyArg_ParseTuple (args, const_cast< char * >("s"), &name))
+ {
+ OUString typeName ( OUString::createFromAscii( name ) );
+ Runtime runtime;
+ Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(typeName);
+ if( a.getValueType().getTypeClass() ==
+ com::sun::star::uno::TypeClass_INTERFACE )
+ {
+ // a idl constant cannot be an instance of an uno-object, thus
+ // this cannot be a constant
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno.getConstantByName: " ).append( typeName );
+ buf.appendAscii( "is not a constant" );
+ throw RuntimeException(buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ PyRef constant = runtime.any2PyObject( a );
+ ret = constant.getAcquired();
+ }
+ }
+ catch( NoSuchElementException & e )
+ {
+ // to the python programmer, this is a runtime exception,
+ // do not support tweakings with the type system
+ RuntimeException runExc( e.Message, Reference< XInterface > () );
+ raisePyExceptionWithAny( makeAny( runExc ) );
+ }
+ catch( com::sun::star::script::CannotConvertException & e)
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ catch( com::sun::star::lang::IllegalArgumentException & e)
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ catch( RuntimeException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ return ret;
+}
+
+static PyObject *checkType( PyObject *, PyObject *args )
+{
+ if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
+ {
+ OStringBuffer buf;
+ buf.append( "pyuno.checkType : expecting one uno.Type argument" );
+ PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
+ return NULL;
+ }
+ PyObject *obj = PyTuple_GetItem( args, 0 );
+
+ try
+ {
+ PyType2Type( obj );
+ }
+ catch( RuntimeException & e)
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ return NULL;
+ }
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
+static PyObject *checkEnum( PyObject *, PyObject *args )
+{
+ if( !PyTuple_Check( args ) || PyTuple_Size( args) != 1 )
+ {
+ OStringBuffer buf;
+ buf.append( "pyuno.checkType : expecting one uno.Type argument" );
+ PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
+ return NULL;
+ }
+ PyObject *obj = PyTuple_GetItem( args, 0 );
+
+ try
+ {
+ PyEnum2Enum( obj );
+ }
+ catch( RuntimeException & e)
+ {
+ raisePyExceptionWithAny( makeAny( e) );
+ return NULL;
+ }
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
+static PyObject *getClass( PyObject *, PyObject *args )
+{
+ PyObject *obj = extractOneStringArg( args, "pyuno.getClass");
+ if( ! obj )
+ return NULL;
+
+ try
+ {
+ Runtime runtime;
+ PyRef ret = getClass(
+ OUString( PyString_AsString( obj), strlen(PyString_AsString(obj)),RTL_TEXTENCODING_ASCII_US),
+ runtime );
+ Py_XINCREF( ret.get() );
+ return ret.get();
+ }
+ catch( RuntimeException & e)
+ {
+ // NOOPT !!!
+ // gcc 3.2.3 crashes here in the regcomp test scenario
+ // only since migration to python 2.3.4 ???? strange thing
+ // optimization switched off for this module !
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ return NULL;
+}
+
+static PyObject *isInterface( PyObject *, PyObject *args )
+{
+
+ if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
+ {
+ PyObject *obj = PyTuple_GetItem( args, 0 );
+ Runtime r;
+ return PyInt_FromLong( isInterfaceClass( r, obj ) );
+ }
+ return PyInt_FromLong( 0 );
+}
+
+static PyObject * generateUuid( PyObject *, PyObject * )
+{
+ Sequence< sal_Int8 > seq( 16 );
+ rtl_createUuid( (sal_uInt8*)seq.getArray() , 0 , sal_False );
+ PyRef ret;
+ try
+ {
+ Runtime runtime;
+ ret = runtime.any2PyObject( makeAny( seq ) );
+ }
+ catch( RuntimeException & e )
+ {
+ raisePyExceptionWithAny( makeAny(e) );
+ }
+ return ret.getAcquired();
+}
+
+static PyObject *systemPathToFileUrl( PyObject *, PyObject * args )
+{
+ PyObject *obj = extractOneStringArg( args, "pyuno.systemPathToFileUrl" );
+ if( ! obj )
+ return NULL;
+
+ OUString sysPath = pyString2ustring( obj );
+ OUString url;
+ osl::FileBase::RC e = osl::FileBase::getFileURLFromSystemPath( sysPath, url );
+
+ if( e != osl::FileBase::E_None )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "Couldn't convert " );
+ buf.append( sysPath );
+ buf.appendAscii( " to a file url for reason (" );
+ buf.append( (sal_Int32) e );
+ buf.appendAscii( ")" );
+ raisePyExceptionWithAny(
+ makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
+ return NULL;
+ }
+ return ustring2PyUnicode( url ).getAcquired();
+}
+
+static PyObject * fileUrlToSystemPath( PyObject *, PyObject * args )
+{
+ PyObject *obj = extractOneStringArg( args, "pyuno.fileUrlToSystemPath" );
+ if( ! obj )
+ return NULL;
+
+ OUString url = pyString2ustring( obj );
+ OUString sysPath;
+ osl::FileBase::RC e = osl::FileBase::getSystemPathFromFileURL( url, sysPath );
+
+ if( e != osl::FileBase::E_None )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "Couldn't convert file url " );
+ buf.append( sysPath );
+ buf.appendAscii( " to a system path for reason (" );
+ buf.append( (sal_Int32) e );
+ buf.appendAscii( ")" );
+ raisePyExceptionWithAny(
+ makeAny( RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () )));
+ return NULL;
+ }
+ return ustring2PyUnicode( sysPath ).getAcquired();
+}
+
+static PyObject * absolutize( PyObject *, PyObject * args )
+{
+ if( PyTuple_Check( args ) && PyTuple_Size( args ) == 2 )
+ {
+ OUString ouPath = pyString2ustring( PyTuple_GetItem( args , 0 ) );
+ OUString ouRel = pyString2ustring( PyTuple_GetItem( args, 1 ) );
+ OUString ret;
+ oslFileError e = osl_getAbsoluteFileURL( ouPath.pData, ouRel.pData, &(ret.pData) );
+ if( e != osl_File_E_None )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "Couldn't absolutize " );
+ buf.append( ouRel );
+ buf.appendAscii( " using root " );
+ buf.append( ouPath );
+ buf.appendAscii( " for reason (" );
+ buf.append( (sal_Int32) e );
+ buf.appendAscii( ")" );
+
+ PyErr_SetString(
+ PyExc_OSError,
+ OUStringToOString(buf.makeStringAndClear(),osl_getThreadTextEncoding()));
+ return 0;
+ }
+ return ustring2PyUnicode( ret ).getAcquired();
+ }
+ return 0;
+}
+
+static PyObject * invoke ( PyObject *, PyObject * args )
+{
+ PyObject *ret = 0;
+ if( PyTuple_Check( args ) && PyTuple_Size( args ) == 3 )
+ {
+ PyObject *object = PyTuple_GetItem( args, 0 );
+
+ if( PyString_Check( PyTuple_GetItem( args, 1 ) ) )
+ {
+ const char *name = PyString_AsString( PyTuple_GetItem( args, 1 ) );
+ if( PyTuple_Check( PyTuple_GetItem( args , 2 )))
+ {
+ ret = PyUNO_invoke( object, name , PyTuple_GetItem( args, 2 ) );
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "uno.invoke expects a tuple as 3rd argument, got " );
+ buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 2) ) ) );
+ PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "uno.invoke expected a string as 2nd argument, got " );
+ buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 1) ) ) );
+ PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "uno.invoke expects object, name, (arg1, arg2, ... )\n" );
+ PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
+ }
+ return ret;
+}
+
+static PyObject *getCurrentContext( PyObject *, PyObject * )
+{
+ PyRef ret;
+ try
+ {
+ Runtime runtime;
+ ret = runtime.any2PyObject(
+ makeAny( com::sun::star::uno::getCurrentContext() ) );
+ }
+ catch( com::sun::star::uno::Exception & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ return ret.getAcquired();
+}
+
+static PyObject *setCurrentContext( PyObject *, PyObject * args )
+{
+ PyRef ret;
+ try
+ {
+ if( PyTuple_Check( args ) && PyTuple_Size( args ) == 1 )
+ {
+
+ Runtime runtime;
+ Any a = runtime.pyObject2Any( PyTuple_GetItem( args, 0 ) );
+
+ Reference< com::sun::star::uno::XCurrentContext > context;
+
+ if( (a.hasValue() && (a >>= context)) || ! a.hasValue() )
+ {
+ ret = com::sun::star::uno::setCurrentContext( context ) ? Py_True : Py_False;
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "uno.setCurrentContext expects an XComponentContext implementation, got " );
+ buf.append( PyString_AsString( PyObject_Str( PyTuple_GetItem( args, 0) ) ) );
+ PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "uno.setCurrentContext expects exactly one argument (the current Context)\n" );
+ PyErr_SetString( PyExc_RuntimeError, buf.makeStringAndClear() );
+ }
+ }
+ catch( com::sun::star::uno::Exception & e )
+ {
+ raisePyExceptionWithAny( makeAny( e ) );
+ }
+ return ret.getAcquired();
+}
+
+}
+
+struct PyMethodDef PyUNOModule_methods [] =
+{
+ {const_cast< char * >("getComponentContext"), getComponentContext, 1, NULL},
+ {const_cast< char * >("_createUnoStructHelper"), createUnoStructHelper, 2, NULL},
+ {const_cast< char * >("getTypeByName"), getTypeByName, 1, NULL},
+ {const_cast< char * >("getConstantByName"), getConstantByName,1, NULL},
+ {const_cast< char * >("getClass"), getClass,1, NULL},
+ {const_cast< char * >("checkEnum"), checkEnum, 1, NULL},
+ {const_cast< char * >("checkType"), checkType, 1, NULL},
+ {const_cast< char * >("generateUuid"), generateUuid,0, NULL},
+ {const_cast< char * >("systemPathToFileUrl"),systemPathToFileUrl,1, NULL},
+ {const_cast< char * >("fileUrlToSystemPath"),fileUrlToSystemPath,1, NULL},
+ {const_cast< char * >("absolutize"),absolutize,2, NULL},
+ {const_cast< char * >("isInterface"),isInterface,1, NULL},
+ {const_cast< char * >("invoke"),invoke, 2, NULL},
+ {const_cast< char * >("setCurrentContext"),setCurrentContext,1, NULL},
+ {const_cast< char * >("getCurrentContext"),getCurrentContext,1, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+}
+
+extern "C" PY_DLLEXPORT void initpyuno()
+{
+ // noop when called already, otherwise needed to allow multiple threads
+ PyEval_InitThreads();
+ Py_InitModule (const_cast< char * >("pyuno"), PyUNOModule_methods);
+}
diff --git a/pyuno/source/module/pyuno_runtime.cxx b/pyuno/source/module/pyuno_runtime.cxx
new file mode 100644
index 000000000000..754ce05e599e
--- /dev/null
+++ b/pyuno/source/module/pyuno_runtime.cxx
@@ -0,0 +1,1058 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "pyuno_impl.hxx"
+
+#include <osl/thread.h>
+#include <osl/module.h>
+#include <osl/process.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/bootstrap.hxx>
+#include <locale.h>
+
+#include <typelib/typedescription.hxx>
+
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+
+using rtl::OUString;
+using rtl::OUStringToOString;
+using rtl::OUStringBuffer;
+using rtl::OStringBuffer;
+using rtl::OString;
+
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::TypeDescription;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Type;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::XComponentContext;
+using com::sun::star::lang::XSingleServiceFactory;
+using com::sun::star::lang::XUnoTunnel;
+using com::sun::star::reflection::XIdlReflection;
+using com::sun::star::script::XTypeConverter;
+using com::sun::star::script::XInvocationAdapterFactory2;
+using com::sun::star::script::XInvocation;
+using com::sun::star::beans::XMaterialHolder;
+using com::sun::star::beans::XIntrospection;
+
+namespace pyuno
+{
+#define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
+
+static PyTypeObject RuntimeImpl_Type =
+{
+ PyObject_HEAD_INIT (&PyType_Type)
+ 0,
+ const_cast< char * >("pyuno_runtime"),
+ sizeof (RuntimeImpl),
+ 0,
+ (destructor) RuntimeImpl::del,
+ (printfunc) 0,
+ (getattrfunc) 0,
+ (setattrfunc) 0,
+ (cmpfunc) 0,
+ (reprfunc) 0,
+ 0,
+ 0,
+ 0,
+ (hashfunc) 0,
+ (ternaryfunc) 0,
+ (reprfunc) 0,
+ (getattrofunc)0,
+ (setattrofunc)0,
+ NULL,
+ 0,
+ NULL,
+ (traverseproc)0,
+ (inquiry)0,
+ (richcmpfunc)0,
+ 0,
+ (getiterfunc)0,
+ (iternextfunc)0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (descrgetfunc)0,
+ (descrsetfunc)0,
+ 0,
+ (initproc)0,
+ (allocfunc)0,
+ (newfunc)0,
+ (freefunc)0,
+ (inquiry)0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ (destructor)0
+#if PY_VERSION_HEX >= 0x02060000
+ , 0
+#endif
+};
+
+/*----------------------------------------------------------------------
+ Runtime implementation
+ -----------------------------------------------------------------------*/
+static void getRuntimeImpl( PyRef & globalDict, PyRef &runtimeImpl )
+ throw ( com::sun::star::uno::RuntimeException )
+{
+ PyThreadState * state = PyThreadState_Get();
+ if( ! state )
+ {
+ throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "python global interpreter must be held (thread must be attached)" )),
+ Reference< XInterface > () );
+ }
+
+ globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));
+
+ if( ! globalDict.is() ) // FATAL !
+ {
+ throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "can't find __main__ module" )), Reference< XInterface > ());
+ }
+ runtimeImpl = PyDict_GetItemString( globalDict.get() , "pyuno_runtime" );
+}
+
+static PyRef importUnoModule( ) throw ( RuntimeException )
+{
+ PyRef globalDict = PyRef( PyModule_GetDict(PyImport_AddModule(const_cast< char * >("__main__"))));
+ // import the uno module
+ PyRef module( PyImport_ImportModule( const_cast< char * >("uno") ), SAL_NO_ACQUIRE );
+ if( PyErr_Occurred() )
+ {
+ PyRef excType, excValue, excTraceback;
+ PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
+ PyRef str( PyObject_Repr( excTraceback.get() ), SAL_NO_ACQUIRE );
+
+ OUStringBuffer buf;
+ buf.appendAscii( "python object raised an unknown exception (" );
+ PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE );
+ buf.appendAscii( PyString_AsString( valueRep.get())).appendAscii( ", traceback follows\n" );
+ buf.appendAscii( PyString_AsString( str.get() ) );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ PyRef dict( PyModule_GetDict( module.get() ) );
+ return dict;
+}
+
+static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile )
+{
+ *pLevel = LogLevel::NONE;
+ *ppFile = 0;
+ OUString fileName;
+ osl_getModuleURLFromFunctionAddress(
+ reinterpret_cast< oslGenericFunction >(readLoggingConfig),
+ (rtl_uString **) &fileName );
+ fileName = OUString( fileName.getStr(), fileName.lastIndexOf( '/' )+1 );
+ fileName += OUString::createFromAscii( SAL_CONFIGFILE("pyuno") );
+ rtl::Bootstrap bootstrapHandle( fileName );
+
+ OUString str;
+ if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGLEVEL" ), str ) )
+ {
+ if( str.equalsAscii( "NONE" ) )
+ *pLevel = LogLevel::NONE;
+ else if( str.equalsAscii( "CALL" ) )
+ *pLevel = LogLevel::CALL;
+ else if( str.equalsAscii( "ARGS" ) )
+ *pLevel = LogLevel::ARGS;
+ else
+ {
+ fprintf( stderr, "unknown loglevel %s\n",
+ OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
+ }
+ }
+ if( *pLevel > LogLevel::NONE )
+ {
+ *ppFile = stdout;
+ if( bootstrapHandle.getFrom( USTR_ASCII( "PYUNO_LOGTARGET" ), str ) )
+ {
+ if( str.equalsAscii( "stdout" ) )
+ *ppFile = stdout;
+ else if( str.equalsAscii( "stderr" ) )
+ *ppFile = stderr;
+ else
+ {
+ oslProcessInfo data;
+ data.Size = sizeof( data );
+ osl_getProcessInfo(
+ 0 , osl_Process_IDENTIFIER , &data );
+ osl_getSystemPathFromFileURL( str.pData, &str.pData);
+ OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
+ o += ".";
+ o += OString::valueOf( (sal_Int32)data.Ident );
+
+ *ppFile = fopen( o.getStr() , "w" );
+ if ( *ppFile )
+ {
+ // do not buffer (useful if e.g. analyzing a crash)
+ setvbuf( *ppFile, 0, _IONBF, 0 );
+ }
+ else
+ {
+ fprintf( stderr, "couldn't create file %s\n",
+ OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ }
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------
+ RuntimeImpl implementations
+ *-------------------------------------------------------------------*/
+PyRef stRuntimeImpl::create( const Reference< XComponentContext > &ctx )
+ throw( com::sun::star::uno::RuntimeException )
+{
+ RuntimeImpl *me = PyObject_New (RuntimeImpl, &RuntimeImpl_Type);
+ if( ! me )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "cannot instantiate pyuno::RuntimeImpl" ) ),
+ Reference< XInterface > () );
+ me->cargo = 0;
+ // must use a different struct here, as the PyObject_New
+ // makes C++ unusable
+ RuntimeCargo *c = new RuntimeCargo();
+ readLoggingConfig( &(c->logLevel) , &(c->logFile) );
+ log( c, LogLevel::CALL, "Instantiating pyuno bridge" );
+
+ c->valid = 1;
+ c->xContext = ctx;
+ c->xInvocation = Reference< XSingleServiceFactory > (
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Invocation" ) ),
+ ctx ),
+ UNO_QUERY );
+ if( ! c->xInvocation.is() )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation service" ) ),
+ Reference< XInterface > () );
+
+ c->xTypeConverter = Reference< XTypeConverter > (
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.Converter" ) ),
+ ctx ),
+ UNO_QUERY );
+ if( ! c->xTypeConverter.is() )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate typeconverter service" )),
+ Reference< XInterface > () );
+
+ c->xCoreReflection = Reference< XIdlReflection > (
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.CoreReflection" ) ),
+ ctx ),
+ UNO_QUERY );
+ if( ! c->xCoreReflection.is() )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate corereflection service" )),
+ Reference< XInterface > () );
+
+ c->xAdapterFactory = Reference< XInvocationAdapterFactory2 > (
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.InvocationAdapterFactory" ) ),
+ ctx ),
+ UNO_QUERY );
+ if( ! c->xAdapterFactory.is() )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate invocation adapter factory service" )),
+ Reference< XInterface > () );
+
+ c->xIntrospection = Reference< XIntrospection > (
+ ctx->getServiceManager()->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.Introspection" ) ),
+ ctx ),
+ UNO_QUERY );
+ if( ! c->xIntrospection.is() )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't instantiate introspection service" )),
+ Reference< XInterface > () );
+
+ Any a = ctx->getValueByName(OUString(
+ RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theTypeDescriptionManager" )) );
+ a >>= c->xTdMgr;
+ if( ! c->xTdMgr.is() )
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "pyuno: couldn't retrieve typedescriptionmanager" )),
+ Reference< XInterface > () );
+
+ me->cargo =c;
+ return PyRef( reinterpret_cast< PyObject * > ( me ), SAL_NO_ACQUIRE );
+}
+
+void stRuntimeImpl::del(PyObject* self)
+{
+ RuntimeImpl *me = reinterpret_cast< RuntimeImpl * > ( self );
+ if( me->cargo->logFile )
+ fclose( me->cargo->logFile );
+ delete me->cargo;
+ PyObject_Del (self);
+}
+
+
+void Runtime::initialize( const Reference< XComponentContext > & ctx )
+ throw ( RuntimeException )
+{
+ PyRef globalDict, runtime;
+ getRuntimeImpl( globalDict , runtime );
+ RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
+
+ if( runtime.is() && impl->cargo->valid )
+ {
+ throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "pyuno runtime has already been initialized before" ) ),
+ Reference< XInterface > () );
+ }
+ PyRef keep( RuntimeImpl::create( ctx ) );
+ PyDict_SetItemString( globalDict.get(), "pyuno_runtime" , keep.get() );
+ Py_XINCREF( keep.get() );
+}
+
+
+bool Runtime::isInitialized() throw ( RuntimeException )
+{
+ PyRef globalDict, runtime;
+ getRuntimeImpl( globalDict , runtime );
+ RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
+ return runtime.is() && impl->cargo->valid;
+}
+
+void Runtime::finalize() throw (RuntimeException)
+{
+ PyRef globalDict, runtime;
+ getRuntimeImpl( globalDict , runtime );
+ RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
+ if( !runtime.is() || ! impl->cargo->valid )
+ {
+ throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "pyuno bridge must have been initialized before finalizing" )),
+ Reference< XInterface > () );
+ }
+ impl->cargo->valid = false;
+ impl->cargo->xInvocation.clear();
+ impl->cargo->xContext.clear();
+ impl->cargo->xTypeConverter.clear();
+}
+
+Runtime::Runtime() throw( RuntimeException )
+ : impl( 0 )
+{
+ PyRef globalDict, runtime;
+ getRuntimeImpl( globalDict , runtime );
+ if( ! runtime.is() )
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("pyuno runtime is not initialized, "
+ "(the pyuno.bootstrap needs to be called before using any uno classes)")),
+ Reference< XInterface > () );
+ }
+ impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
+ Py_XINCREF( runtime.get() );
+}
+
+Runtime::Runtime( const Runtime & r )
+{
+ impl = r.impl;
+ Py_XINCREF( reinterpret_cast< PyObject * >(impl) );
+}
+
+Runtime::~Runtime()
+{
+ Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
+}
+
+Runtime & Runtime::operator = ( const Runtime & r )
+{
+ PyRef temp( reinterpret_cast< PyObject * >(r.impl) );
+ Py_XINCREF( temp.get() );
+ Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
+ impl = r.impl;
+ return *this;
+}
+
+PyRef Runtime::any2PyObject (const Any &a ) const
+ throw ( com::sun::star::script::CannotConvertException,
+ com::sun::star::lang::IllegalArgumentException,
+ RuntimeException)
+{
+ if( ! impl->cargo->valid )
+ {
+ throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "pyuno runtime must be initialized before calling any2PyObject" )),
+ Reference< XInterface > () );
+ }
+
+ switch (a.getValueTypeClass ())
+ {
+ case typelib_TypeClass_VOID:
+ {
+ Py_INCREF (Py_None);
+ return PyRef(Py_None);
+ }
+ case typelib_TypeClass_CHAR:
+ {
+ sal_Unicode c = *(sal_Unicode*)a.getValue();
+ return PyRef( PyUNO_char_new( c , *this ), SAL_NO_ACQUIRE );
+ }
+ case typelib_TypeClass_BOOLEAN:
+ {
+ sal_Bool b = sal_Bool();
+ if ((a >>= b) && b)
+ return Py_True;
+ else
+ return Py_False;
+ }
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_LONG:
+ {
+ sal_Int32 l = 0;
+ a >>= l;
+ return PyRef( PyInt_FromLong (l), SAL_NO_ACQUIRE );
+ }
+ case typelib_TypeClass_UNSIGNED_LONG:
+ {
+ sal_uInt32 l = 0;
+ a >>= l;
+ return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
+ }
+ case typelib_TypeClass_HYPER:
+ {
+ sal_Int64 l = 0;
+ a >>= l;
+ return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
+ }
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ sal_uInt64 l = 0;
+ a >>= l;
+ return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
+ }
+ case typelib_TypeClass_FLOAT:
+ {
+ float f = 0.0;
+ a >>= f;
+ return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
+ }
+ case typelib_TypeClass_DOUBLE:
+ {
+ double d = 0.0;
+ a >>= d;
+ return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE);
+ }
+ case typelib_TypeClass_STRING:
+ {
+ OUString tmp_ostr;
+ a >>= tmp_ostr;
+ return ustring2PyUnicode( tmp_ostr );
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ Type t;
+ a >>= t;
+ OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
+ return PyRef(
+ PyUNO_Type_new (
+ o.getStr(), (com::sun::star::uno::TypeClass)t.getTypeClass(), *this),
+ SAL_NO_ACQUIRE);
+ }
+ case typelib_TypeClass_ANY:
+ {
+ //I don't think this can happen.
+ Py_INCREF (Py_None);
+ return Py_None;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ sal_Int32 l = *(sal_Int32 *) a.getValue();
+ TypeDescription desc( a.getValueType() );
+ if( desc.is() )
+ {
+ desc.makeComplete();
+ typelib_EnumTypeDescription *pEnumDesc =
+ (typelib_EnumTypeDescription *) desc.get();
+ for( int i = 0 ; i < pEnumDesc->nEnumValues ; i ++ )
+ {
+ if( pEnumDesc->pEnumValues[i] == l )
+ {
+ OString v = OUStringToOString( pEnumDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US);
+ OString e = OUStringToOString( pEnumDesc->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US);
+ return PyRef( PyUNO_Enum_new(e.getStr(),v.getStr(), *this ), SAL_NO_ACQUIRE );
+ }
+ }
+ }
+ OUStringBuffer buf;
+ buf.appendAscii( "Any carries enum " );
+ buf.append( a.getValueType().getTypeName());
+ buf.appendAscii( " with invalid value " ).append( l );
+ throw RuntimeException( buf.makeStringAndClear() , Reference< XInterface > () );
+ }
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ {
+ PyRef excClass = getClass( a.getValueType().getTypeName(), *this );
+ PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE);
+ PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE );
+ PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() );
+ PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.get() ), SAL_NO_ACQUIRE );
+ if( ! ret.is() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "Couldn't instantiate python representation of structered UNO type " );
+ buf.append( a.getValueType().getTypeName() );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+
+ if( com::sun::star::uno::TypeClass_EXCEPTION == a.getValueTypeClass() )
+ {
+ // add the message in a standard python way !
+ PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
+
+ // assuming that the Message is always the first member, wuuuu
+ void *pData = (void*)a.getValue();
+ OUString message = *(OUString * )pData;
+ PyRef pymsg = ustring2PyString( message );
+ PyTuple_SetItem( args.get(), 0 , pymsg.getAcquired() );
+ // the exception base functions want to have an "args" tuple,
+ // which contains the message
+ PyObject_SetAttrString( ret.get(), const_cast< char * >("args"), args.get() );
+ }
+ return ret;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ Sequence<Any> s;
+
+ Sequence< sal_Int8 > byteSequence;
+ if( a >>= byteSequence )
+ {
+ // byte sequence is treated in a special way because of peformance reasons
+ // @since 0.9.2
+ return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE );
+ }
+ else
+ {
+ Reference< XTypeConverter > tc = getImpl()->cargo->xTypeConverter;
+ Reference< XSingleServiceFactory > ssf = getImpl()->cargo->xInvocation;
+ tc->convertTo (a, ::getCppuType (&s)) >>= s;
+ PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE);
+ int i=0;
+ OUString errMsg;
+ try
+ {
+ for ( i = 0; i < s.getLength (); i++)
+ {
+ PyRef element;
+ element = any2PyObject (tc->convertTo (s[i], s[i].getValueType() ));
+ OSL_ASSERT( element.is() );
+ PyTuple_SetItem( tuple.get(), i, element.getAcquired() );
+ }
+ }
+ catch( com::sun::star::uno::Exception & )
+ {
+ for( ; i < s.getLength() ; i ++ )
+ {
+ Py_INCREF( Py_None );
+ PyTuple_SetItem( tuple.get(), i, Py_None );
+ }
+ throw;
+ }
+ return tuple;
+ }
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ Reference< XUnoTunnel > tunnel;
+ a >>= tunnel;
+ if( tunnel.is() )
+ {
+ sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
+ if( that )
+ return ((Adapter*)sal::static_int_cast< sal_IntPtr >(that))->getWrappedObject();
+ }
+ //This is just like the struct case:
+ return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE );
+ }
+ default:
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "Unknonwn UNO type class " );
+ buf.append( (sal_Int32 ) a.getValueTypeClass() );
+ throw RuntimeException(buf.makeStringAndClear( ), Reference< XInterface > () );
+ }
+ }
+ //We shouldn't be here...
+ Py_INCREF( Py_None );
+ return Py_None;
+}
+
+static Sequence< Type > invokeGetTypes( const Runtime & r , PyObject * o )
+{
+ Sequence< Type > ret;
+
+ PyRef method( PyObject_GetAttrString( o , const_cast< char * >("getTypes") ), SAL_NO_ACQUIRE );
+ raiseInvocationTargetExceptionWhenNeeded( r );
+ if( method.is() && PyCallable_Check( method.get() ) )
+ {
+ PyRef types( PyObject_CallObject( method.get(), 0 ) , SAL_NO_ACQUIRE );
+ raiseInvocationTargetExceptionWhenNeeded( r );
+ if( types.is() && PyTuple_Check( types.get() ) )
+ {
+ int size = PyTuple_Size( types.get() );
+
+ // add the XUnoTunnel interface for uno object identity concept (hack)
+ ret.realloc( size + 1 );
+ for( int i = 0 ; i < size ; i ++ )
+ {
+ Any a = r.pyObject2Any(PyTuple_GetItem(types.get(),i));
+ a >>= ret[i];
+ }
+ ret[size] = getCppuType( (Reference< com::sun::star::lang::XUnoTunnel> *) 0 );
+ }
+ }
+ return ret;
+}
+
+Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) const
+ throw ( com::sun::star::uno::RuntimeException )
+{
+ if( ! impl->cargo->valid )
+ {
+ throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "pyuno runtime must be initialized before calling any2PyObject" )),
+ Reference< XInterface > () );
+ }
+
+ Any a;
+ PyObject *o = source.get();
+ if( Py_None == o )
+ {
+
+ }
+ else if (PyInt_Check (o))
+ {
+ if( o == Py_True )
+ {
+ sal_Bool b = sal_True;
+ a = Any( &b, getBooleanCppuType() );
+ }
+ else if ( o == Py_False )
+ {
+ sal_Bool b = sal_False;
+ a = Any( &b, getBooleanCppuType() );
+ }
+ else
+ {
+ sal_Int32 l = (sal_Int32) PyInt_AsLong( o );
+ if( l < 128 && l >= -128 )
+ {
+ sal_Int8 b = (sal_Int8 ) l;
+ a <<= b;
+ }
+ else if( l <= 0x7fff && l >= -0x8000 )
+ {
+ sal_Int16 s = (sal_Int16) l;
+ a <<= s;
+ }
+ else
+ {
+ a <<= l;
+ }
+ }
+ }
+ else if (PyLong_Check (o))
+ {
+ sal_Int64 l = (sal_Int64)PyLong_AsLong (o);
+ if( l < 128 && l >= -128 )
+ {
+ sal_Int8 b = (sal_Int8 ) l;
+ a <<= b;
+ }
+ else if( l <= 0x7fff && l >= -0x8000 )
+ {
+ sal_Int16 s = (sal_Int16) l;
+ a <<= s;
+ }
+ else if( l <= SAL_CONST_INT64(0x7fffffff) &&
+ l >= -SAL_CONST_INT64(0x80000000) )
+ {
+ sal_Int32 l32 = (sal_Int32) l;
+ a <<= l32;
+ }
+ else
+ {
+ a <<= l;
+ }
+ }
+ else if (PyFloat_Check (o))
+ {
+ double d = PyFloat_AsDouble (o);
+ a <<= d;
+ }
+ else if (PyString_Check (o))
+ a <<= pyString2ustring(o);
+ else if( PyUnicode_Check( o ) )
+ a <<= pyString2ustring(o);
+ else if (PyTuple_Check (o))
+ {
+ Sequence<Any> s (PyTuple_Size (o));
+ for (int i = 0; i < PyTuple_Size (o); i++)
+ {
+ s[i] = pyObject2Any (PyTuple_GetItem (o, i), mode );
+ }
+ a <<= s;
+ }
+ else
+ {
+ Runtime runtime;
+ // should be removed, in case ByteSequence gets derived from String
+ if( PyObject_IsInstance( o, getByteSequenceClass( runtime ).get() ) )
+ {
+ PyRef str(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE);
+ Sequence< sal_Int8 > seq;
+ if( PyString_Check( str.get() ) )
+ {
+ seq = Sequence<sal_Int8 > (
+ (sal_Int8*) PyString_AsString(str.get()), PyString_Size(str.get()));
+ }
+ a <<= seq;
+ }
+ else
+ if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) )
+ {
+ Type t = PyType2Type( o );
+ a <<= t;
+ }
+ else if( PyObject_IsInstance( o, getEnumClass( runtime ).get() ) )
+ {
+ a = PyEnum2Enum( o );
+ }
+ else if( isInstanceOfStructOrException( o ) )
+ {
+ PyRef struc(PyObject_GetAttrString( o , const_cast< char * >("value") ),SAL_NO_ACQUIRE);
+ PyUNO * obj = (PyUNO*)struc.get();
+ Reference< XMaterialHolder > holder( obj->members->xInvocation, UNO_QUERY );
+ if( holder.is( ) )
+ a = holder->getMaterial();
+ else
+ {
+ throw RuntimeException(
+ USTR_ASCII( "struct or exception wrapper does not support XMaterialHolder" ),
+ Reference< XInterface > () );
+ }
+ }
+ else if( PyObject_IsInstance( o, getPyUnoClass( runtime ).get() ) )
+ {
+ PyUNO* o_pi;
+ o_pi = (PyUNO*) o;
+ if (o_pi->members->wrappedObject.getValueTypeClass () ==
+ com::sun::star::uno::TypeClass_STRUCT ||
+ o_pi->members->wrappedObject.getValueTypeClass () ==
+ com::sun::star::uno::TypeClass_EXCEPTION)
+ {
+ Reference<XMaterialHolder> my_mh (o_pi->members->xInvocation, UNO_QUERY);
+
+ if (!my_mh.is ())
+ {
+ throw RuntimeException(
+ USTR_ASCII( "struct wrapper does not support XMaterialHolder" ),
+ Reference< XInterface > () );
+ }
+ else
+ a = my_mh->getMaterial ();
+ }
+ else
+ {
+ a = o_pi->members->wrappedObject;
+ }
+ }
+ else if( PyObject_IsInstance( o, getCharClass( runtime ).get() ) )
+ {
+ sal_Unicode c = PyChar2Unicode( o );
+ a.setValue( &c, getCharCppuType( ));
+ }
+ else if( PyObject_IsInstance( o, getAnyClass( runtime ).get() ) )
+ {
+ if( ACCEPT_UNO_ANY == mode )
+ {
+ a = pyObject2Any( PyRef( PyObject_GetAttrString( o , const_cast< char * >("value") ), SAL_NO_ACQUIRE) );
+ Type t;
+ pyObject2Any( PyRef( PyObject_GetAttrString( o, const_cast< char * >("type") ), SAL_NO_ACQUIRE ) ) >>= t;
+
+ try
+ {
+ a = getImpl()->cargo->xTypeConverter->convertTo( a, t );
+ }
+ catch( com::sun::star::uno::Exception & e )
+ {
+ throw RuntimeException( e.Message, e.Context );
+ }
+ }
+ else
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "uno.Any instance not accepted during method call, "
+ "use uno.invoke instead" ) ),
+ Reference< XInterface > () );
+ }
+ }
+ else
+ {
+ Reference< XInterface > mappedObject;
+ Reference< XInvocation > adapterObject;
+
+ // instance already mapped out to the world ?
+ PyRef2Adapter::iterator ii = impl->cargo->mappedObjects.find( PyRef( o ) );
+ if( ii != impl->cargo->mappedObjects.end() )
+ {
+ adapterObject = ii->second;
+ }
+
+ if( adapterObject.is() )
+ {
+ // object got already bridged !
+ Reference< com::sun::star::lang::XUnoTunnel > tunnel( adapterObject, UNO_QUERY );
+
+ Adapter *pAdapter = ( Adapter * )
+ sal::static_int_cast< sal_IntPtr >(
+ tunnel->getSomething(
+ ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
+
+ mappedObject = impl->cargo->xAdapterFactory->createAdapter(
+ adapterObject, pAdapter->getWrappedTypes() );
+ }
+ else
+ {
+ Sequence< Type > interfaces = invokeGetTypes( *this, o );
+ if( interfaces.getLength() )
+ {
+ Adapter *pAdapter = new Adapter( o, interfaces );
+ mappedObject =
+ getImpl()->cargo->xAdapterFactory->createAdapter(
+ pAdapter, interfaces );
+
+ // keep a list of exported objects to ensure object identity !
+ impl->cargo->mappedObjects[ PyRef(o) ] =
+ com::sun::star::uno::WeakReference< XInvocation > ( pAdapter );
+ }
+ }
+ if( mappedObject.is() )
+ {
+ a = com::sun::star::uno::makeAny( mappedObject );
+ }
+ else
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "Couldn't convert " );
+ PyRef reprString( PyObject_Str( o ) , SAL_NO_ACQUIRE );
+ buf.appendAscii( PyString_AsString( reprString.get() ) );
+ buf.appendAscii( " to a UNO type" );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ }
+ }
+ return a;
+}
+
+Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const
+{
+ PyRef str;
+ Any ret;
+ if( excTraceback.is() )
+ {
+ PyRef unoModule( impl ? impl->cargo->getUnoModule() : 0 );
+ if( unoModule.is() )
+ {
+ PyRef extractTraceback(
+ PyDict_GetItemString(unoModule.get(),"_uno_extract_printable_stacktrace" ) );
+
+ if( extractTraceback.is() )
+ {
+ PyRef args( PyTuple_New( 1), SAL_NO_ACQUIRE );
+ PyTuple_SetItem( args.get(), 0, excTraceback.getAcquired() );
+ str = PyRef( PyObject_CallObject( extractTraceback.get(),args.get() ), SAL_NO_ACQUIRE);
+ }
+ else
+ {
+ str = PyRef(
+ PyString_FromString( "Couldn't find uno._uno_extract_printable_stacktrace" ),
+ SAL_NO_ACQUIRE );
+ }
+ }
+ else
+ {
+ str = PyRef(
+ PyString_FromString( "Couldn't find uno.py, no stacktrace available" ),
+ SAL_NO_ACQUIRE );
+ }
+
+ }
+ else
+ {
+ // it may occur, that no traceback is given (e.g. only native code below)
+ str = PyRef( PyString_FromString( "no traceback available" ), SAL_NO_ACQUIRE);
+ }
+
+ if( isInstanceOfStructOrException( excValue.get() ) )
+ {
+ ret = pyObject2Any( excValue );
+ }
+ else
+ {
+ OUStringBuffer buf;
+ PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
+ if( typeName.is() )
+ {
+ buf.appendAscii( PyString_AsString( typeName.get() ) );
+ }
+ else
+ {
+ buf.appendAscii( "no typename available" );
+ }
+ buf.appendAscii( ": " );
+ PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
+ if( valueRep.is() )
+ {
+ buf.appendAscii( PyString_AsString( valueRep.get()));
+ }
+ else
+ {
+ buf.appendAscii( "Couldn't convert exception value to a string" );
+ }
+ buf.appendAscii( ", traceback follows\n" );
+ if( str.is() )
+ {
+ buf.appendAscii( PyString_AsString( str.get() ) );
+ }
+ else
+ {
+ buf.appendAscii( ", no traceback available\n" );
+ }
+ RuntimeException e;
+ e.Message = buf.makeStringAndClear();
+ ret = com::sun::star::uno::makeAny( e );
+ }
+ return ret;
+}
+
+
+static const char * g_NUMERICID = "pyuno.lcNumeric";
+static ::std::vector< rtl::OString > g_localeList;
+
+static const char *ensureUnlimitedLifetime( const char *str )
+{
+ int size = g_localeList.size();
+ int i;
+ for( i = 0 ; i < size ; i ++ )
+ {
+ if( 0 == strcmp( g_localeList[i].getStr(), str ) )
+ break;
+ }
+ if( i == size )
+ {
+ g_localeList.push_back( str );
+ }
+ return g_localeList[i].getStr();
+}
+
+
+PyThreadAttach::PyThreadAttach( PyInterpreterState *interp)
+ throw ( com::sun::star::uno::RuntimeException )
+{
+ tstate = PyThreadState_New( interp );
+ if( !tstate )
+ throw RuntimeException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM( "Couldn't create a pythreadstate" ) ),
+ Reference< XInterface > () );
+ PyEval_AcquireThread( tstate);
+ // set LC_NUMERIC to "C"
+ const char * oldLocale =
+ ensureUnlimitedLifetime( setlocale( LC_NUMERIC, 0 ) );
+ setlocale( LC_NUMERIC, "C" );
+ PyRef locale( // python requires C locale
+ PyLong_FromVoidPtr( (void*)oldLocale ), SAL_NO_ACQUIRE);
+ PyDict_SetItemString(
+ PyThreadState_GetDict(), g_NUMERICID, locale.get() );
+}
+
+PyThreadAttach::~PyThreadAttach()
+{
+ PyObject *value =
+ PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
+ if( value )
+ setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
+ PyThreadState_Clear( tstate );
+ PyEval_ReleaseThread( tstate );
+ PyThreadState_Delete( tstate );
+
+}
+
+PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException )
+{
+ tstate = PyThreadState_Get();
+ PyObject *value =
+ PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
+ if( value )
+ setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
+ PyEval_ReleaseThread( tstate );
+}
+
+ /** Acquires the global interpreter lock again
+
+ */
+PyThreadDetach::~PyThreadDetach()
+{
+ PyEval_AcquireThread( tstate );
+// PyObject *value =
+// PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
+
+ // python requires C LC_NUMERIC locale,
+ // always set even when it is already "C"
+ setlocale( LC_NUMERIC, "C" );
+}
+
+
+PyRef RuntimeCargo::getUnoModule()
+{
+ if( ! dictUnoModule.is() )
+ {
+ dictUnoModule = importUnoModule();
+ }
+ return dictUnoModule;
+}
+}
diff --git a/pyuno/source/module/pyuno_type.cxx b/pyuno/source/module/pyuno_type.cxx
new file mode 100644
index 000000000000..7bf284bbfeed
--- /dev/null
+++ b/pyuno/source/module/pyuno_type.cxx
@@ -0,0 +1,431 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "pyuno_impl.hxx"
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+
+#include <typelib/typedescription.hxx>
+
+using rtl::OString;
+using rtl::OUString;
+using rtl::OUStringBuffer;
+using rtl::OUStringToOString;
+using rtl::OStringBuffer;
+
+using com::sun::star::uno::TypeClass;
+using com::sun::star::uno::Type;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::TypeDescription;
+
+#define USTR_ASCII(x) rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
+namespace pyuno
+{
+const char *typeClassToString( TypeClass t )
+{
+ const char * ret = 0;
+ switch (t)
+ {
+ case com::sun::star::uno::TypeClass_VOID:
+ ret = "VOID"; break;
+ case com::sun::star::uno::TypeClass_CHAR:
+ ret = "CHAR"; break;
+ case com::sun::star::uno::TypeClass_BOOLEAN:
+ ret = "BOOLEAN"; break;
+ case com::sun::star::uno::TypeClass_BYTE:
+ ret = "BYTE"; break;
+ case com::sun::star::uno::TypeClass_SHORT:
+ ret = "SHORT"; break;
+ case com::sun::star::uno::TypeClass_UNSIGNED_SHORT:
+ ret = "UNSIGNED_SHORT"; break;
+ case com::sun::star::uno::TypeClass_LONG:
+ ret = "LONG"; break;
+ case com::sun::star::uno::TypeClass_UNSIGNED_LONG:
+ ret = "UNSIGNED_LONG"; break;
+ case com::sun::star::uno::TypeClass_HYPER:
+ ret = "HYPER"; break;
+ case com::sun::star::uno::TypeClass_UNSIGNED_HYPER:
+ ret = "UNSIGNED_HYPER"; break;
+ case com::sun::star::uno::TypeClass_FLOAT:
+ ret = "FLOAT"; break;
+ case com::sun::star::uno::TypeClass_DOUBLE:
+ ret = "DOUBLE"; break;
+ case com::sun::star::uno::TypeClass_STRING:
+ ret = "STRING"; break;
+ case com::sun::star::uno::TypeClass_TYPE:
+ ret = "TYPE"; break;
+ case com::sun::star::uno::TypeClass_ANY:
+ ret = "ANY";break;
+ case com::sun::star::uno::TypeClass_ENUM:
+ ret = "ENUM";break;
+ case com::sun::star::uno::TypeClass_STRUCT:
+ ret = "STRUCT"; break;
+ case com::sun::star::uno::TypeClass_EXCEPTION:
+ ret = "EXCEPTION"; break;
+ case com::sun::star::uno::TypeClass_SEQUENCE:
+ ret = "SEQUENCE"; break;
+ case com::sun::star::uno::TypeClass_INTERFACE:
+ ret = "INTERFACE"; break;
+ case com::sun::star::uno::TypeClass_TYPEDEF:
+ ret = "TYPEDEF"; break;
+ case com::sun::star::uno::TypeClass_UNION:
+ ret = "UNION"; break;
+ case com::sun::star::uno::TypeClass_ARRAY:
+ ret = "ARRAY"; break;
+ case com::sun::star::uno::TypeClass_SERVICE:
+ ret = "SERVICE"; break;
+ case com::sun::star::uno::TypeClass_MODULE:
+ ret = "MODULE"; break;
+ case com::sun::star::uno::TypeClass_INTERFACE_METHOD:
+ ret = "INTERFACE_METHOD"; break;
+ case com::sun::star::uno::TypeClass_INTERFACE_ATTRIBUTE:
+ ret = "INTERFACE_ATTRIBUTE"; break;
+ default:
+ ret = "UNKNOWN"; break;
+ }
+ return ret;
+}
+
+static PyRef getClass( const Runtime & r , const char * name)
+{
+ return PyRef( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*) name ) );
+}
+
+PyRef getTypeClass( const Runtime & r )
+{
+ return getClass( r , "Type" );
+}
+
+PyRef getEnumClass( const Runtime & r )
+{
+ return getClass( r , "Enum" );
+}
+
+PyRef getCharClass( const Runtime & r )
+{
+ return getClass( r , "Char" );
+}
+
+PyRef getByteSequenceClass( const Runtime & r )
+{
+ return getClass( r , "ByteSequence" );
+}
+
+PyRef getAnyClass( const Runtime & r )
+{
+ return getClass( r , "Any" );
+}
+
+
+sal_Unicode PyChar2Unicode( PyObject *obj ) throw ( RuntimeException )
+{
+ PyRef value( PyObject_GetAttrString( obj, const_cast< char * >("value") ), SAL_NO_ACQUIRE );
+ if( ! PyUnicode_Check( value.get() ) )
+ {
+ throw RuntimeException(
+ USTR_ASCII( "attribute value of uno.Char is not a unicode string" ),
+ Reference< XInterface > () );
+ }
+
+ if( PyUnicode_GetSize( value.get() ) < 1 )
+ {
+ throw RuntimeException(
+ USTR_ASCII( "uno.Char contains an empty unicode string" ),
+ Reference< XInterface > () );
+ }
+
+ sal_Unicode c = (sal_Unicode)PyUnicode_AsUnicode( value.get() )[0];
+ return c;
+}
+
+Any PyEnum2Enum( PyObject *obj ) throw ( RuntimeException )
+{
+ Any ret;
+ PyRef typeName( PyObject_GetAttrString( obj,const_cast< char * >("typeName") ), SAL_NO_ACQUIRE);
+ PyRef value( PyObject_GetAttrString( obj, const_cast< char * >("value") ), SAL_NO_ACQUIRE);
+ if( !PyString_Check( typeName.get() ) || ! PyString_Check( value.get() ) )
+ {
+ throw RuntimeException(
+ USTR_ASCII( "attributes typeName and/or value of uno.Enum are not strings" ),
+ Reference< XInterface > () );
+ }
+
+ OUString strTypeName( OUString::createFromAscii( PyString_AsString( typeName.get() ) ) );
+ char *stringValue = PyString_AsString( value.get() );
+
+ TypeDescription desc( strTypeName );
+ if( desc.is() )
+ {
+ if(desc.get()->eTypeClass != typelib_TypeClass_ENUM )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno.checkEnum: " ).append(strTypeName).appendAscii( "is a " );
+ buf.appendAscii(
+ typeClassToString( (com::sun::star::uno::TypeClass) desc.get()->eTypeClass));
+ buf.appendAscii( ", expected ENUM" );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
+ }
+
+ desc.makeComplete();
+
+ typelib_EnumTypeDescription *pEnumDesc = (typelib_EnumTypeDescription*) desc.get();
+ int i = 0;
+ for( i = 0; i < pEnumDesc->nEnumValues ; i ++ )
+ {
+ if( (*((OUString *)&pEnumDesc->ppEnumNames[i])).compareToAscii( stringValue ) == 0 )
+ {
+ break;
+ }
+ }
+ if( i == pEnumDesc->nEnumValues )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "value " ).appendAscii( stringValue ).appendAscii( "is unknown in enum " );
+ buf.appendAscii( PyString_AsString( typeName.get() ) );
+ throw RuntimeException( buf.makeStringAndClear(), Reference<XInterface> () );
+ }
+ ret = Any( &pEnumDesc->pEnumValues[i], desc.get()->pWeakRef );
+ }
+ else
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "enum " ).appendAscii( PyString_AsString(typeName.get()) ).appendAscii( " is unknown" );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface> () );
+ }
+ return ret;
+}
+
+
+Type PyType2Type( PyObject * o ) throw(RuntimeException )
+{
+ PyRef pyName( PyObject_GetAttrString( o, const_cast< char * >("typeName") ), SAL_NO_ACQUIRE);
+ if( !PyString_Check( pyName.get() ) )
+ {
+ throw RuntimeException(
+ USTR_ASCII( "type object does not have typeName property" ),
+ Reference< XInterface > () );
+ }
+
+ PyRef pyTC( PyObject_GetAttrString( o, const_cast< char * >("typeClass") ), SAL_NO_ACQUIRE );
+ Any enumValue = PyEnum2Enum( pyTC.get() );
+
+ OUString name( OUString::createFromAscii( PyString_AsString( pyName.get() ) ) );
+ TypeDescription desc( name );
+ if( ! desc.is() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "type " ).append(name).appendAscii( " is unknown" );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ if( desc.get()->eTypeClass != (typelib_TypeClass) *(sal_Int32*)enumValue.getValue() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno.checkType: " ).append(name).appendAscii( " is a " );
+ buf.appendAscii( typeClassToString( (TypeClass) desc.get()->eTypeClass) );
+ buf.appendAscii( ", but type got construct with typeclass " );
+ buf.appendAscii( typeClassToString( (TypeClass) *(sal_Int32*)enumValue.getValue() ) );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ return desc.get()->pWeakRef;
+}
+
+PyObject *importToGlobal(PyObject *str, PyObject *dict, PyObject *target)
+{
+ // maybe a constant ?
+ PyObject *ret = 0;
+ OUString name = pyString2ustring(str);
+ try
+ {
+ Runtime runtime;
+ TypeDescription desc(name );
+ desc.makeComplete();
+ if( desc.is() )
+ {
+ com::sun::star::uno::TypeClass tc =
+ (com::sun::star::uno::TypeClass)desc.get()->eTypeClass;
+
+ PyRef typesModule( PyDict_GetItemString( dict, "unotypes" ) );
+ if( ! typesModule.is() || ! PyModule_Check( typesModule.get() ))
+ {
+ typesModule = PyRef( PyModule_New( const_cast< char * >("unotypes") ), SAL_NO_ACQUIRE );
+ Py_INCREF( typesModule.get() );
+ PyDict_SetItemString( dict, "unotypes" , typesModule.get() );
+ }
+ PyModule_AddObject(
+ typesModule.get(),
+ PyString_AsString( target ),
+ PyUNO_Type_new( PyString_AsString(str),tc,runtime ) );
+
+ if( com::sun::star::uno::TypeClass_EXCEPTION == tc ||
+ com::sun::star::uno::TypeClass_STRUCT == tc )
+ {
+ PyRef exc = getClass( name, runtime );
+ PyDict_SetItem( dict, target, exc.getAcquired() );
+ }
+ else if( com::sun::star::uno::TypeClass_ENUM == tc )
+ {
+ // introduce all enums into the dictionary !
+ typelib_EnumTypeDescription *pDesc =
+ (typelib_EnumTypeDescription *) desc.get();
+ for( int i = 0 ; i < pDesc->nEnumValues; i ++ )
+ {
+ OString enumElementName(
+ OUStringToOString( pDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US) );
+ PyDict_SetItemString(
+ dict, (char*)enumElementName.getStr(),
+ PyUNO_Enum_new(PyString_AsString(str) , enumElementName.getStr(), runtime ) );
+ }
+ }
+ Py_INCREF( Py_None );
+ ret = Py_None;
+ }
+ else
+ {
+ Any a = runtime.getImpl()->cargo->xTdMgr->getByHierarchicalName(name);
+ if(a.hasValue())
+ {
+ PyRef constant = runtime.any2PyObject( a );
+ if( constant.is() )
+ {
+ Py_INCREF( constant.get() );
+ PyDict_SetItem( dict, target , constant.get());
+ ret = constant.get();
+ }
+ else
+ {
+ OStringBuffer buf;
+ buf.append( "constant " ).append(PyString_AsString(str)).append( " unknown" );
+ PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
+ }
+ }
+ else
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno.imp unknown type " );
+ buf.append( name );
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() );
+ }
+ }
+ }
+ catch( com::sun::star::container::NoSuchElementException & )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "pyuno.imp unknown type " );
+ buf.append( name );
+ PyErr_SetString(
+ PyExc_RuntimeError,
+ OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US).getStr() );
+ }
+ catch( com::sun::star::script::CannotConvertException & e )
+ {
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+ catch( com::sun::star::lang::IllegalArgumentException & e )
+ {
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ) );
+ }
+ catch( RuntimeException &e )
+ {
+ raisePyExceptionWithAny( com::sun::star::uno::makeAny( e ));
+ }
+ return ret;
+}
+
+static PyObject* callCtor( const Runtime &r , const char * clazz, const PyRef & args )
+{
+ PyRef code( PyDict_GetItemString( r.getImpl()->cargo->getUnoModule().get(), (char*)clazz ) );
+ if( ! code.is() )
+ {
+ OStringBuffer buf;
+ buf.append( "couldn't access uno." );
+ buf.append( clazz );
+ PyErr_SetString( PyExc_RuntimeError, buf.getStr() );
+ return NULL;
+ }
+ PyRef instance( PyObject_CallObject( code.get(), args.get() ), SAL_NO_ACQUIRE);
+ Py_XINCREF( instance.get() );
+ return instance.get();
+
+}
+
+
+PyObject *PyUNO_Enum_new( const char *enumBase, const char *enumValue, const Runtime &r )
+{
+ PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
+ PyTuple_SetItem( args.get() , 0 , PyString_FromString( enumBase ) );
+ PyTuple_SetItem( args.get() , 1 , PyString_FromString( enumValue ) );
+
+ return callCtor( r, "Enum" , args );
+}
+
+
+PyObject* PyUNO_Type_new (const char *typeName , TypeClass t , const Runtime &r )
+{
+ // retrieve type object
+ PyRef args( PyTuple_New( 2 ), SAL_NO_ACQUIRE );
+
+ PyTuple_SetItem( args.get() , 0 , PyString_FromString( typeName ) );
+ PyObject *typeClass = PyUNO_Enum_new( "com.sun.star.uno.TypeClass" , typeClassToString(t), r );
+ if( ! typeClass )
+ return NULL;
+ PyTuple_SetItem( args.get() , 1 , typeClass);
+
+ return callCtor( r, "Type" , args );
+}
+
+PyObject* PyUNO_char_new ( sal_Unicode val , const Runtime &r )
+{
+ // retrieve type object
+ PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
+
+ Py_UNICODE u[2];
+ u[0] = val;
+ u[1] = 0;
+ PyTuple_SetItem( args.get() , 0 , PyUnicode_FromUnicode( u ,1) );
+
+ return callCtor( r, "Char" , args );
+}
+
+PyObject *PyUNO_ByteSequence_new(
+ const com::sun::star::uno::Sequence< sal_Int8 > &byteSequence, const Runtime &r )
+{
+ PyRef str(
+ PyString_FromStringAndSize( (char*)byteSequence.getConstArray(), byteSequence.getLength()),
+ SAL_NO_ACQUIRE );
+ PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
+ PyTuple_SetItem( args.get() , 0 , str.getAcquired() );
+ return callCtor( r, "ByteSequence" , args );
+
+}
+}
diff --git a/pyuno/source/module/pyuno_util.cxx b/pyuno/source/module/pyuno_util.cxx
new file mode 100644
index 000000000000..e8dd1f704d7a
--- /dev/null
+++ b/pyuno/source/module/pyuno_util.cxx
@@ -0,0 +1,249 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "pyuno_impl.hxx"
+
+#include <time.h>
+#include <osl/thread.h>
+
+#include <typelib/typedescription.hxx>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/time.h>
+
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+
+using rtl::OUStringToOString;
+using rtl::OUString;
+using rtl::OString;
+using rtl::OStringBuffer;
+using rtl::OUStringBuffer;
+
+
+using com::sun::star::uno::TypeDescription;
+using com::sun::star::uno::Sequence;
+using com::sun::star::uno::Reference;
+using com::sun::star::uno::XInterface;
+using com::sun::star::uno::Any;
+using com::sun::star::uno::Type;
+using com::sun::star::uno::UNO_QUERY;
+using com::sun::star::uno::TypeClass;
+using com::sun::star::uno::RuntimeException;
+using com::sun::star::uno::XComponentContext;
+using com::sun::star::lang::XSingleServiceFactory;
+using com::sun::star::script::XTypeConverter;
+using com::sun::star::beans::XMaterialHolder;
+
+#define USTR_ASCII(x) OUString( RTL_CONSTASCII_USTRINGPARAM( x ) )
+namespace pyuno
+{
+PyRef ustring2PyUnicode( const OUString & str )
+{
+ PyRef ret;
+#if Py_UNICODE_SIZE == 2
+ // YD force conversion since python/2 uses wchar_t
+ ret = PyRef( PyUnicode_FromUnicode( (const Py_UNICODE*)str.getStr(), str.getLength() ), SAL_NO_ACQUIRE );
+#else
+ OString sUtf8(OUStringToOString(str, RTL_TEXTENCODING_UTF8));
+ ret = PyRef( PyUnicode_DecodeUTF8( sUtf8.getStr(), sUtf8.getLength(), NULL) , SAL_NO_ACQUIRE );
+#endif
+ return ret;
+}
+
+PyRef ustring2PyString( const OUString &str )
+{
+ OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
+ return PyRef( PyString_FromString( o.getStr() ), SAL_NO_ACQUIRE );
+}
+
+OUString pyString2ustring( PyObject *pystr )
+{
+ OUString ret;
+ if( PyUnicode_Check( pystr ) )
+ {
+#if Py_UNICODE_SIZE == 2
+ ret = OUString( (sal_Unicode * ) PyUnicode_AS_UNICODE( pystr ) );
+#else
+ PyObject* pUtf8 = PyUnicode_AsUTF8String(pystr);
+ ret = OUString(PyString_AsString(pUtf8), PyString_Size(pUtf8), RTL_TEXTENCODING_UTF8);
+ Py_DECREF(pUtf8);
+#endif
+ }
+ else
+ {
+ char *name = PyString_AsString(pystr );
+ ret = OUString( name, strlen(name), osl_getThreadTextEncoding() );
+ }
+ return ret;
+}
+
+PyRef getObjectFromUnoModule( const Runtime &runtime, const char * func )
+ throw ( RuntimeException )
+{
+ PyRef object(PyDict_GetItemString( runtime.getImpl()->cargo->getUnoModule().get(), (char*)func ) );
+ if( !object.is() )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( "couldn't find core function " );
+ buf.appendAscii( func );
+ throw RuntimeException(buf.makeStringAndClear(),Reference< XInterface >());
+ }
+ return object;
+}
+
+
+//------------------------------------------------------------------------------------
+// Logging
+//------------------------------------------------------------------------------------
+
+bool isLog( RuntimeCargo * cargo, sal_Int32 loglevel )
+{
+ return cargo && cargo->logFile && loglevel <= cargo->logLevel;
+}
+
+void log( RuntimeCargo * cargo, sal_Int32 level, const rtl::OUString &logString )
+{
+ log( cargo, level, OUStringToOString( logString, osl_getThreadTextEncoding() ).getStr() );
+}
+
+void log( RuntimeCargo * cargo, sal_Int32 level, const char *str )
+{
+ if( isLog( cargo, level ) )
+ {
+ static const char *strLevel[] = { "NONE", "CALL", "ARGS" };
+
+ TimeValue systemTime;
+ TimeValue localTime;
+ oslDateTime localDateTime;
+
+ osl_getSystemTime( &systemTime );
+ osl_getLocalTimeFromSystemTime( &systemTime, &localTime );
+ osl_getDateTimeFromTimeValue( &localTime, &localDateTime );
+
+ fprintf( cargo->logFile,
+ "%4i-%02i-%02i %02i:%02i:%02i,%03lu [%s,tid %ld]: %s\n",
+ localDateTime.Year,
+ localDateTime.Month,
+ localDateTime.Day,
+ localDateTime.Hours,
+ localDateTime.Minutes,
+ localDateTime.Seconds,
+ sal::static_int_cast< unsigned long >(
+ localDateTime.NanoSeconds/1000000),
+ strLevel[level],
+ sal::static_int_cast< long >(
+ (sal_Int32) osl_getThreadIdentifier( 0)),
+ str );
+ }
+}
+
+namespace {
+
+void appendPointer(rtl::OUStringBuffer & buffer, void * pointer) {
+ buffer.append(
+ sal::static_int_cast< sal_Int64 >(
+ reinterpret_cast< sal_IntPtr >(pointer)),
+ 16);
+}
+
+}
+
+void logException( RuntimeCargo *cargo, const char *intro,
+ void * ptr, const rtl::OUString &aFunctionName,
+ const void * data, const com::sun::star::uno::Type & type )
+{
+ if( isLog( cargo, LogLevel::CALL ) )
+ {
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( intro );
+ appendPointer(buf, ptr);
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("].") );
+ buf.append( aFunctionName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " = " ) );
+ buf.append(
+ val2str( data, type.getTypeLibType(), VAL2STR_MODE_SHALLOW ) );
+ log( cargo,LogLevel::CALL, buf.makeStringAndClear() );
+ }
+
+}
+
+void logReply(
+ RuntimeCargo *cargo,
+ const char *intro,
+ void * ptr,
+ const rtl::OUString & aFunctionName,
+ const Any &returnValue,
+ const Sequence< Any > & aParams )
+{
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( intro );
+ appendPointer(buf, ptr);
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("].") );
+ buf.append( aFunctionName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("()=") );
+ if( isLog( cargo, LogLevel::ARGS ) )
+ {
+ buf.append(
+ val2str( returnValue.getValue(), returnValue.getValueTypeRef(), VAL2STR_MODE_SHALLOW) );
+ for( int i = 0; i < aParams.getLength() ; i ++ )
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", " ) );
+ buf.append(
+ val2str( aParams[i].getValue(), aParams[i].getValueTypeRef(), VAL2STR_MODE_SHALLOW) );
+ }
+ }
+ log( cargo,LogLevel::CALL, buf.makeStringAndClear() );
+
+}
+
+void logCall( RuntimeCargo *cargo, const char *intro,
+ void * ptr, const rtl::OUString & aFunctionName,
+ const Sequence< Any > & aParams )
+{
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( intro );
+ appendPointer(buf, ptr);
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("].") );
+ buf.append( aFunctionName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("(") );
+ if( isLog( cargo, LogLevel::ARGS ) )
+ {
+ for( int i = 0; i < aParams.getLength() ; i ++ )
+ {
+ if( i > 0 )
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", " ) );
+ buf.append(
+ val2str( aParams[i].getValue(), aParams[i].getValueTypeRef(), VAL2STR_MODE_SHALLOW) );
+ }
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
+ log( cargo,LogLevel::CALL, buf.makeStringAndClear() );
+}
+
+
+}
diff --git a/pyuno/source/module/uno.py b/pyuno/source/module/uno.py
new file mode 100644
index 000000000000..f61b3c925d36
--- /dev/null
+++ b/pyuno/source/module/uno.py
@@ -0,0 +1,352 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+import sys
+
+import pyuno
+import __builtin__
+import socket # since on Windows sal3.dll no longer calls WSAStartup
+
+# all functions and variables starting with a underscore (_) must be considered private
+# and can be changed at any time. Don't use them
+_g_ctx = pyuno.getComponentContext( )
+_g_delegatee = __builtin__.__dict__["__import__"]
+
+def getComponentContext():
+ """ returns the UNO component context, that was used to initialize the python runtime.
+ """
+ return _g_ctx
+
+def getConstantByName( constant ):
+ "Looks up the value of a idl constant by giving its explicit name"
+ return pyuno.getConstantByName( constant )
+
+def getTypeByName( typeName):
+ """ returns a uno.Type instance of the type given by typeName. In case the
+ type does not exist, a com.sun.star.uno.RuntimeException is raised.
+ """
+ return pyuno.getTypeByName( typeName )
+
+def createUnoStruct( typeName, *args ):
+ """creates a uno struct or exception given by typeName. The parameter args may
+ 1) be empty. In this case, you get a default constructed uno structure.
+ ( e.g. createUnoStruct( "com.sun.star.uno.Exception" ) )
+ 2) be a sequence with exactly one element, that contains an instance of typeName.
+ In this case, a copy constructed instance of typeName is returned
+ ( e.g. createUnoStruct( "com.sun.star.uno.Exception" , e ) )
+ 3) be a sequence, where the length of the sequence must match the number of
+ elements within typeName (e.g.
+ createUnoStruct( "com.sun.star.uno.Exception", "foo error" , self) ). The
+ elements with in the sequence must match the type of each struct element,
+ otherwise an exception is thrown.
+ """
+ return getClass(typeName)( *args )
+
+def getClass( typeName ):
+ """returns the class of a concrete uno exception, struct or interface
+ """
+ return pyuno.getClass(typeName)
+
+def isInterface( obj ):
+ """returns true, when obj is a class of a uno interface"""
+ return pyuno.isInterface( obj )
+
+def generateUuid():
+ "returns a 16 byte sequence containing a newly generated uuid or guid, see rtl/uuid.h "
+ return pyuno.generateUuid()
+
+def systemPathToFileUrl( systemPath ):
+ "returns a file-url for the given system path"
+ return pyuno.systemPathToFileUrl( systemPath )
+
+def fileUrlToSystemPath( url ):
+ "returns a system path (determined by the system, the python interpreter is running on)"
+ return pyuno.fileUrlToSystemPath( url )
+
+def absolutize( path, relativeUrl ):
+ "returns an absolute file url from the given urls"
+ return pyuno.absolutize( path, relativeUrl )
+
+def getCurrentContext():
+ """Returns the currently valid current context.
+ see http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context
+ for an explanation on the current context concept
+ """
+ return pyuno.getCurrentContext()
+
+def setCurrentContext( newContext ):
+ """Sets newContext as new uno current context. The newContext must
+ implement the XCurrentContext interface. The implemenation should
+ handle the desired properties and delegate unknown properties to the
+ old context. Ensure to reset the old one when you leave your stack ...
+ see http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context
+ """
+ return pyuno.setCurrentContext( newContext )
+
+
+class Enum:
+ "Represents a UNO idl enum, use an instance of this class to explicitly pass a boolean to UNO"
+ #typeName the name of the enum as a string
+ #value the actual value of this enum as a string
+ def __init__(self,typeName, value):
+ self.typeName = typeName
+ self.value = value
+ pyuno.checkEnum( self )
+
+ def __repr__(self):
+ return "<uno.Enum %s (%r)>" % (self.typeName, self.value)
+
+ def __eq__(self, that):
+ if not isinstance(that, Enum):
+ return False
+ return (self.typeName == that.typeName) and (self.value == that.value)
+
+class Type:
+ "Represents a UNO type, use an instance of this class to explicitly pass a boolean to UNO"
+# typeName # Name of the UNO type
+# typeClass # python Enum of TypeClass, see com/sun/star/uno/TypeClass.idl
+ def __init__(self, typeName, typeClass):
+ self.typeName = typeName
+ self.typeClass = typeClass
+ pyuno.checkType(self)
+ def __repr__(self):
+ return "<Type instance %s (%r)>" % (self.typeName, self.typeClass)
+
+ def __eq__(self, that):
+ if not isinstance(that, Type):
+ return False
+ return self.typeClass == that.typeClass and self.typeName == that.typeName
+
+ def __hash__(self):
+ return self.typeName.__hash__()
+
+class Bool(object):
+ """Represents a UNO boolean, use an instance of this class to explicitly
+ pass a boolean to UNO.
+ Note: This class is deprecated. Use python's True and False directly instead
+ """
+ def __new__(cls, value):
+ if isinstance(value, (str, unicode)) and value == "true":
+ return True
+ if isinstance(value, (str, unicode)) and value == "false":
+ return False
+ if value:
+ return True
+ return False
+
+class Char:
+ "Represents a UNO char, use an instance of this class to explicitly pass a char to UNO"
+ # @param value pass a Unicode string with length 1
+ def __init__(self,value):
+ assert isinstance(value, unicode)
+ assert len(value) == 1
+ self.value=value
+
+ def __repr__(self):
+ return "<Char instance %s>" % (self.value, )
+
+ def __eq__(self, that):
+ if isinstance(that, (str, unicode)):
+ if len(that) > 1:
+ return False
+ return self.value == that[0]
+ if isinstance(that, Char):
+ return self.value == that.value
+ return False
+
+# Suggested by Christian, but still some open problems which need to be solved first
+#
+#class ByteSequence(str):
+#
+# def __repr__(self):
+# return "<ByteSequence instance %s>" % str.__repr__(self)
+
+ # for a little bit compatitbility; setting value is not possible as
+ # strings are immutable
+# def _get_value(self):
+# return self
+#
+# value = property(_get_value)
+
+class ByteSequence:
+ def __init__(self, value):
+ if isinstance(value, str):
+ self.value = value
+ elif isinstance(value, ByteSequence):
+ self.value = value.value
+ else:
+ raise TypeError("expected string or bytesequence")
+
+ def __repr__(self):
+ return "<ByteSequence instance '%s'>" % (self.value, )
+
+ def __eq__(self, that):
+ if isinstance( that, ByteSequence):
+ return self.value == that.value
+ if isinstance(that, str):
+ return self.value == that
+ return False
+
+ def __len__(self):
+ return len(self.value)
+
+ def __getitem__(self, index):
+ return self.value[index]
+
+ def __iter__( self ):
+ return self.value.__iter__()
+
+ def __add__( self , b ):
+ if isinstance( b, str ):
+ return ByteSequence( self.value + b )
+ elif isinstance( b, ByteSequence ):
+ return ByteSequence( self.value + b.value )
+ raise TypeError( "expected string or ByteSequence as operand" )
+
+ def __hash__( self ):
+ return self.value.hash()
+
+
+class Any:
+ "use only in connection with uno.invoke() to pass an explicit typed any"
+ def __init__(self, type, value ):
+ if isinstance( type, Type ):
+ self.type = type
+ else:
+ self.type = getTypeByName( type )
+ self.value = value
+
+def invoke( object, methodname, argTuple ):
+ "use this function to pass exactly typed anys to the callee (using uno.Any)"
+ return pyuno.invoke( object, methodname, argTuple )
+
+#---------------------------------------------------------------------------------------
+# don't use any functions beyond this point, private section, likely to change
+#---------------------------------------------------------------------------------------
+#def _uno_import( name, globals={}, locals={}, fromlist=[], level=-1 ):
+def _uno_import( name, *optargs, **kwargs ):
+ try:
+# print "optargs = " + repr(optargs)
+ return _g_delegatee( name, *optargs, **kwargs )
+ except ImportError:
+ # process optargs
+ globals, locals, fromlist = list(optargs)[:3] + [kwargs.get('globals',{}), kwargs.get('locals',{}), kwargs.get('fromlist',[])][len(optargs):]
+ if not fromlist:
+ raise
+ modnames = name.split( "." )
+ mod = None
+ d = sys.modules
+ for x in modnames:
+ if d.has_key(x):
+ mod = d[x]
+ else:
+ mod = pyuno.__class__(x) # How to create a module ??
+ d = mod.__dict__
+
+ RuntimeException = pyuno.getClass( "com.sun.star.uno.RuntimeException" )
+ for x in fromlist:
+ if not d.has_key(x):
+ if x.startswith( "typeOf" ):
+ try:
+ d[x] = pyuno.getTypeByName( name + "." + x[6:len(x)] )
+ except RuntimeException,e:
+ raise ImportError( "type " + name + "." + x[6:len(x)] +" is unknown" )
+ else:
+ try:
+ # check for structs, exceptions or interfaces
+ d[x] = pyuno.getClass( name + "." + x )
+ except RuntimeException,e:
+ # check for enums
+ try:
+ d[x] = Enum( name , x )
+ except RuntimeException,e2:
+ # check for constants
+ try:
+ d[x] = getConstantByName( name + "." + x )
+ except RuntimeException,e3:
+ # no known uno type !
+ raise ImportError( "type "+ name + "." +x + " is unknown" )
+ return mod
+
+# hook into the __import__ chain
+__builtin__.__dict__["__import__"] = _uno_import
+
+# private function, don't use
+def _impl_extractName(name):
+ r = range (len(name)-1,0,-1)
+ for i in r:
+ if name[i] == ".":
+ name = name[i+1:len(name)]
+ break
+ return name
+
+# private, referenced from the pyuno shared library
+def _uno_struct__init__(self,*args):
+ if len(args) == 1 and hasattr(args[0], "__class__") and args[0].__class__ == self.__class__ :
+ self.__dict__["value"] = args[0]
+ else:
+ self.__dict__["value"] = pyuno._createUnoStructHelper(self.__class__.__pyunostruct__,args)
+
+# private, referenced from the pyuno shared library
+def _uno_struct__getattr__(self,name):
+ return __builtin__.getattr(self.__dict__["value"],name)
+
+# private, referenced from the pyuno shared library
+def _uno_struct__setattr__(self,name,value):
+ return __builtin__.setattr(self.__dict__["value"],name,value)
+
+# private, referenced from the pyuno shared library
+def _uno_struct__repr__(self):
+ return repr(self.__dict__["value"])
+
+def _uno_struct__str__(self):
+ return str(self.__dict__["value"])
+
+# private, referenced from the pyuno shared library
+def _uno_struct__eq__(self,cmp):
+ if hasattr(cmp,"value"):
+ return self.__dict__["value"] == cmp.__dict__["value"]
+ return False
+
+# referenced from pyuno shared lib and pythonscript.py
+def _uno_extract_printable_stacktrace( trace ):
+ mod = None
+ try:
+ mod = __import__("traceback")
+ except ImportError,e:
+ pass
+ ret = ""
+ if mod:
+ lst = mod.extract_tb( trace )
+ max = len(lst)
+ for j in range(max):
+ i = lst[max-j-1]
+ ret = ret + " " + str(i[0]) + ":" + \
+ str(i[1]) + " in function " + \
+ str(i[2]) + "() [" + str(i[3]) + "]\n"
+ else:
+ ret = "Couldn't import traceback module"
+ return ret
diff --git a/pyuno/source/module/unohelper.py b/pyuno/source/module/unohelper.py
new file mode 100644
index 000000000000..c59df0597a73
--- /dev/null
+++ b/pyuno/source/module/unohelper.py
@@ -0,0 +1,304 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+import uno
+import pyuno
+import os
+import sys
+
+from com.sun.star.lang import XTypeProvider, XSingleComponentFactory, XServiceInfo
+from com.sun.star.uno import RuntimeException, XCurrentContext
+from com.sun.star.beans.MethodConcept import ALL as METHOD_CONCEPT_ALL
+from com.sun.star.beans.PropertyConcept import ALL as PROPERTY_CONCEPT_ALL
+
+from com.sun.star.reflection.ParamMode import \
+ IN as PARAM_MODE_IN, \
+ OUT as PARAM_MODE_OUT, \
+ INOUT as PARAM_MODE_INOUT
+
+from com.sun.star.beans.PropertyAttribute import \
+ MAYBEVOID as PROP_ATTR_MAYBEVOID, \
+ BOUND as PROP_ATTR_BOUND, \
+ CONSTRAINED as PROP_ATTR_CONSTRAINED, \
+ TRANSIENT as PROP_ATTR_TRANSIENT, \
+ READONLY as PROP_ATTR_READONLY, \
+ MAYBEAMBIGUOUS as PROP_ATTR_MAYBEAMBIGUOUS, \
+ MAYBEDEFAULT as PROP_ATTR_MAYBEDEFAULT, \
+ REMOVEABLE as PROP_ATTR_REMOVEABLE
+
+def _mode_to_str( mode ):
+ ret = "[]"
+ if mode == PARAM_MODE_INOUT:
+ ret = "[inout]"
+ elif mode == PARAM_MODE_OUT:
+ ret = "[out]"
+ elif mode == PARAM_MODE_IN:
+ ret = "[in]"
+ return ret
+
+def _propertymode_to_str( mode ):
+ ret = ""
+ if PROP_ATTR_REMOVEABLE & mode:
+ ret = ret + "removeable "
+ if PROP_ATTR_MAYBEDEFAULT & mode:
+ ret = ret + "maybedefault "
+ if PROP_ATTR_MAYBEAMBIGUOUS & mode:
+ ret = ret + "maybeambigous "
+ if PROP_ATTR_READONLY & mode:
+ ret = ret + "readonly "
+ if PROP_ATTR_TRANSIENT & mode:
+ ret = ret + "tranient "
+ if PROP_ATTR_CONSTRAINED & mode:
+ ret = ret + "constrained "
+ if PROP_ATTR_BOUND & mode:
+ ret = ret + "bound "
+ if PROP_ATTR_MAYBEVOID & mode:
+ ret = ret + "maybevoid "
+ return ret.rstrip()
+
+def inspect( obj , out ):
+ if isinstance( obj, uno.Type ) or \
+ isinstance( obj, uno.Char ) or \
+ isinstance( obj, uno.Bool ) or \
+ isinstance( obj, uno.ByteSequence ) or \
+ isinstance( obj, uno.Enum ) or \
+ isinstance( obj, uno.Any ):
+ out.write( str(obj) + "\n")
+ return
+
+ ctx = uno.getComponentContext()
+ introspection = \
+ ctx.ServiceManager.createInstanceWithContext( "com.sun.star.beans.Introspection", ctx )
+
+ out.write( "Supported services:\n" )
+ if hasattr( obj, "getSupportedServiceNames" ):
+ names = obj.getSupportedServiceNames()
+ for ii in names:
+ out.write( " " + ii + "\n" )
+ else:
+ out.write( " unknown\n" )
+
+ out.write( "Interfaces:\n" )
+ if hasattr( obj, "getTypes" ):
+ interfaces = obj.getTypes()
+ for ii in interfaces:
+ out.write( " " + ii.typeName + "\n" )
+ else:
+ out.write( " unknown\n" )
+
+ access = introspection.inspect( obj )
+ methods = access.getMethods( METHOD_CONCEPT_ALL )
+ out.write( "Methods:\n" )
+ for ii in methods:
+ out.write( " " + ii.ReturnType.Name + " " + ii.Name )
+ args = ii.ParameterTypes
+ infos = ii.ParameterInfos
+ out.write( "( " )
+ for i in range( 0, len( args ) ):
+ if i > 0:
+ out.write( ", " )
+ out.write( _mode_to_str( infos[i].aMode ) + " " + args[i].Name + " " + infos[i].aName )
+ out.write( " )\n" )
+
+ props = access.getProperties( PROPERTY_CONCEPT_ALL )
+ out.write ("Properties:\n" )
+ for ii in props:
+ out.write( " ("+_propertymode_to_str( ii.Attributes ) + ") "+ii.Type.typeName+" "+ii.Name+ "\n" )
+
+def createSingleServiceFactory( clazz, implementationName, serviceNames ):
+ return _FactoryHelper_( clazz, implementationName, serviceNames )
+
+class _ImplementationHelperEntry:
+ def __init__(self, ctor,serviceNames):
+ self.ctor = ctor
+ self.serviceNames = serviceNames
+
+class ImplementationHelper:
+ def __init__(self):
+ self.impls = {}
+
+ def addImplementation( self, ctor, implementationName, serviceNames ):
+ self.impls[implementationName] = _ImplementationHelperEntry(ctor,serviceNames)
+
+ def writeRegistryInfo( self, regKey, smgr ):
+ for i in self.impls.items():
+ keyName = "/"+ i[0] + "/UNO/SERVICES"
+ key = regKey.createKey( keyName )
+ for serviceName in i[1].serviceNames:
+ key.createKey( serviceName )
+ return 1
+
+ def getComponentFactory( self, implementationName , regKey, smgr ):
+ entry = self.impls.get( implementationName, None )
+ if entry == None:
+ raise RuntimeException( implementationName + " is unknown" , None )
+ return createSingleServiceFactory( entry.ctor, implementationName, entry.serviceNames )
+
+ def getSupportedServiceNames( self, implementationName ):
+ entry = self.impls.get( implementationName, None )
+ if entry == None:
+ raise RuntimeException( implementationName + " is unknown" , None )
+ return entry.serviceNames
+
+ def supportsService( self, implementationName, serviceName ):
+ entry = self.impls.get( implementationName,None )
+ if entry == None:
+ raise RuntimeException( implementationName + " is unknown", None )
+ return serviceName in entry.serviceNames
+
+
+class ImplementationEntry:
+ def __init__(self, implName, supportedServices, clazz ):
+ self.implName = implName
+ self.supportedServices = supportedServices
+ self.clazz = clazz
+
+def writeRegistryInfoHelper( smgr, regKey, seqEntries ):
+ for entry in seqEntries:
+ keyName = "/"+ entry.implName + "/UNO/SERVICES"
+ key = regKey.createKey( keyName )
+ for serviceName in entry.supportedServices:
+ key.createKey( serviceName )
+
+def systemPathToFileUrl( systemPath ):
+ "returns a file-url for the given system path"
+ return pyuno.systemPathToFileUrl( systemPath )
+
+def fileUrlToSystemPath( url ):
+ "returns a system path (determined by the system, the python interpreter is running on)"
+ return pyuno.fileUrlToSystemPath( url )
+
+def absolutize( path, relativeUrl ):
+ "returns an absolute file url from the given urls"
+ return pyuno.absolutize( path, relativeUrl )
+
+def getComponentFactoryHelper( implementationName, smgr, regKey, seqEntries ):
+ for x in seqEntries:
+ if x.implName == implementationName:
+ return createSingleServiceFactory( x.clazz, implementationName, x.supportedServices )
+
+def addComponentsToContext( toBeExtendedContext, contextRuntime, componentUrls, loaderName ):
+ smgr = contextRuntime.ServiceManager
+ loader = smgr.createInstanceWithContext( loaderName, contextRuntime )
+ implReg = smgr.createInstanceWithContext( "com.sun.star.registry.ImplementationRegistration",contextRuntime)
+
+ isWin = os.name == 'nt' or os.name == 'dos'
+ isMac = sys.platform == 'darwin'
+ # create a temporary registry
+ for componentUrl in componentUrls:
+ reg = smgr.createInstanceWithContext( "com.sun.star.registry.SimpleRegistry", contextRuntime )
+ reg.open( "", 0, 1 )
+ if not isWin and componentUrl.endswith( ".uno" ): # still allow platform independent naming
+ if isMac:
+ componentUrl = componentUrl + ".dylib"
+ else:
+ componentUrl = componentUrl + ".so"
+
+ implReg.registerImplementation( loaderName,componentUrl, reg )
+ rootKey = reg.getRootKey()
+ implementationKey = rootKey.openKey( "IMPLEMENTATIONS" )
+ implNames = implementationKey.getKeyNames()
+ extSMGR = toBeExtendedContext.ServiceManager
+ for x in implNames:
+ fac = loader.activate( max(x.split("/")),"",componentUrl,rootKey)
+ extSMGR.insert( fac )
+ reg.close()
+
+# never shrinks !
+_g_typeTable = {}
+def _unohelper_getHandle( self):
+ ret = None
+ if _g_typeTable.has_key( self.__class__ ):
+ ret = _g_typeTable[self.__class__]
+ else:
+ names = {}
+ traverse = list(self.__class__.__bases__)
+ while len( traverse ) > 0:
+ item = traverse.pop()
+ bases = item.__bases__
+ if uno.isInterface( item ):
+ names[item.__pyunointerface__] = None
+ elif len(bases) > 0:
+ # the "else if", because we only need the most derived interface
+ traverse = traverse + list(bases)#
+
+ lst = names.keys()
+ types = []
+ for x in lst:
+ t = uno.getTypeByName( x )
+ types.append( t )
+
+ ret = tuple(types) , uno.generateUuid()
+ _g_typeTable[self.__class__] = ret
+ return ret
+
+class Base(XTypeProvider):
+ def getTypes( self ):
+ return _unohelper_getHandle( self )[0]
+ def getImplementationId(self):
+ return _unohelper_getHandle( self )[1]
+
+class CurrentContext(XCurrentContext, Base ):
+ """a current context implementation, which first does a lookup in the given
+ hashmap and if the key cannot be found, it delegates to the predecessor
+ if available
+ """
+ def __init__( self, oldContext, hashMap ):
+ self.hashMap = hashMap
+ self.oldContext = oldContext
+
+ def getValueByName( self, name ):
+ if name in self.hashMap:
+ return self.hashMap[name]
+ elif self.oldContext != None:
+ return self.oldContext.getValueByName( name )
+ else:
+ return None
+
+# -------------------------------------------------
+# implementation details
+# -------------------------------------------------
+class _FactoryHelper_( XSingleComponentFactory, XServiceInfo, Base ):
+ def __init__( self, clazz, implementationName, serviceNames ):
+ self.clazz = clazz
+ self.implementationName = implementationName
+ self.serviceNames = serviceNames
+
+ def getImplementationName( self ):
+ return self.implementationName
+
+ def supportsService( self, ServiceName ):
+ return ServiceName in self.serviceNames
+
+ def getSupportedServiceNames( self ):
+ return self.serviceNames
+
+ def createInstanceWithContext( self, context ):
+ return self.clazz( context )
+
+ def createInstanceWithArgumentsAndContext( self, args, context ):
+ return self.clazz( context, *args )
+