diff options
Diffstat (limited to 'pyuno/source/module/unohelper.py')
-rw-r--r-- | pyuno/source/module/unohelper.py | 304 |
1 files changed, 304 insertions, 0 deletions
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 ) + |