summaryrefslogtreecommitdiffstats
path: root/pyuno/source/module/unohelper.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--pyuno/source/module/unohelper.py297
1 files changed, 297 insertions, 0 deletions
diff --git a/pyuno/source/module/unohelper.py b/pyuno/source/module/unohelper.py
new file mode 100644
index 000000000..cf6f78d63
--- /dev/null
+++ b/pyuno/source/module/unohelper.py
@@ -0,0 +1,297 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# This file incorporates work covered by the following license notice:
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed
+# with this work for additional information regarding copyright
+# ownership. The ASF licenses this file to you under the Apache
+# License, Version 2.0 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.apache.org/licenses/LICENSE-2.0 .
+#
+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, \
+ REMOVABLE as PROP_ATTR_REMOVABLE
+
+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_REMOVABLE & mode:
+ ret = ret + "removable "
+ if PROP_ATTR_MAYBEDEFAULT & mode:
+ ret = ret + "maybedefault "
+ if PROP_ATTR_MAYBEAMBIGUOUS & mode:
+ ret = ret + "maybeambiguous "
+ if PROP_ATTR_READONLY & mode:
+ ret = ret + "readonly "
+ if PROP_ATTR_TRANSIENT & mode:
+ ret = ret + "transient "
+ 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 list(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 is 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 is None:
+ raise RuntimeException( implementationName + " is unknown" , None )
+ return entry.serviceNames
+
+ def supportsService( self, implementationName, serviceName ):
+ entry = self.impls.get( implementationName,None )
+ if entry is 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 self.__class__ in _g_typeTable:
+ 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 = list(names.keys())
+ types = []
+ for x in lst:
+ t = uno.getTypeByName( x )
+ types.append( t )
+
+ ret = tuple(types)
+ _g_typeTable[self.__class__] = ret
+ return ret
+
+class Base(XTypeProvider):
+ def getTypes( self ):
+ return _unohelper_getHandle( self )
+ def getImplementationId(self):
+ return ()
+
+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 is not 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 )
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab: