1a0428e9eSAndrew Rist#************************************************************** 2a0428e9eSAndrew Rist# 3a0428e9eSAndrew Rist# Licensed to the Apache Software Foundation (ASF) under one 4a0428e9eSAndrew Rist# or more contributor license agreements. See the NOTICE file 5a0428e9eSAndrew Rist# distributed with this work for additional information 6a0428e9eSAndrew Rist# regarding copyright ownership. The ASF licenses this file 7a0428e9eSAndrew Rist# to you under the Apache License, Version 2.0 (the 8a0428e9eSAndrew Rist# "License"); you may not use this file except in compliance 9a0428e9eSAndrew Rist# with the License. You may obtain a copy of the License at 10a0428e9eSAndrew Rist# 11a0428e9eSAndrew Rist# http://www.apache.org/licenses/LICENSE-2.0 12a0428e9eSAndrew Rist# 13a0428e9eSAndrew Rist# Unless required by applicable law or agreed to in writing, 14a0428e9eSAndrew Rist# software distributed under the License is distributed on an 15a0428e9eSAndrew Rist# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16a0428e9eSAndrew Rist# KIND, either express or implied. See the License for the 17a0428e9eSAndrew Rist# specific language governing permissions and limitations 18a0428e9eSAndrew Rist# under the License. 19a0428e9eSAndrew Rist# 20a0428e9eSAndrew Rist#************************************************************** 21cdf0e10cSrcweirimport uno 22cdf0e10cSrcweirimport pyuno 23cdf0e10cSrcweirimport os 24cdf0e10cSrcweirimport sys 25cdf0e10cSrcweir 26cdf0e10cSrcweirfrom com.sun.star.lang import XTypeProvider, XSingleComponentFactory, XServiceInfo 27cdf0e10cSrcweirfrom com.sun.star.uno import RuntimeException, XCurrentContext 28cdf0e10cSrcweirfrom com.sun.star.beans.MethodConcept import ALL as METHOD_CONCEPT_ALL 29cdf0e10cSrcweirfrom com.sun.star.beans.PropertyConcept import ALL as PROPERTY_CONCEPT_ALL 30cdf0e10cSrcweir 31cdf0e10cSrcweirfrom com.sun.star.reflection.ParamMode import \ 32cdf0e10cSrcweir IN as PARAM_MODE_IN, \ 33cdf0e10cSrcweir OUT as PARAM_MODE_OUT, \ 34cdf0e10cSrcweir INOUT as PARAM_MODE_INOUT 35cdf0e10cSrcweir 36cdf0e10cSrcweirfrom com.sun.star.beans.PropertyAttribute import \ 37cdf0e10cSrcweir MAYBEVOID as PROP_ATTR_MAYBEVOID, \ 38cdf0e10cSrcweir BOUND as PROP_ATTR_BOUND, \ 39cdf0e10cSrcweir CONSTRAINED as PROP_ATTR_CONSTRAINED, \ 40cdf0e10cSrcweir TRANSIENT as PROP_ATTR_TRANSIENT, \ 41cdf0e10cSrcweir READONLY as PROP_ATTR_READONLY, \ 42cdf0e10cSrcweir MAYBEAMBIGUOUS as PROP_ATTR_MAYBEAMBIGUOUS, \ 43cdf0e10cSrcweir MAYBEDEFAULT as PROP_ATTR_MAYBEDEFAULT, \ 44cdf0e10cSrcweir REMOVEABLE as PROP_ATTR_REMOVEABLE 45cdf0e10cSrcweir 46cdf0e10cSrcweirdef _mode_to_str( mode ): 47cdf0e10cSrcweir ret = "[]" 48cdf0e10cSrcweir if mode == PARAM_MODE_INOUT: 49cdf0e10cSrcweir ret = "[inout]" 50cdf0e10cSrcweir elif mode == PARAM_MODE_OUT: 51cdf0e10cSrcweir ret = "[out]" 52cdf0e10cSrcweir elif mode == PARAM_MODE_IN: 53cdf0e10cSrcweir ret = "[in]" 54cdf0e10cSrcweir return ret 55cdf0e10cSrcweir 56cdf0e10cSrcweirdef _propertymode_to_str( mode ): 57cdf0e10cSrcweir ret = "" 58cdf0e10cSrcweir if PROP_ATTR_REMOVEABLE & mode: 59cdf0e10cSrcweir ret = ret + "removeable " 60cdf0e10cSrcweir if PROP_ATTR_MAYBEDEFAULT & mode: 61cdf0e10cSrcweir ret = ret + "maybedefault " 62cdf0e10cSrcweir if PROP_ATTR_MAYBEAMBIGUOUS & mode: 63cdf0e10cSrcweir ret = ret + "maybeambigous " 64cdf0e10cSrcweir if PROP_ATTR_READONLY & mode: 65cdf0e10cSrcweir ret = ret + "readonly " 66cdf0e10cSrcweir if PROP_ATTR_TRANSIENT & mode: 67cdf0e10cSrcweir ret = ret + "tranient " 68cdf0e10cSrcweir if PROP_ATTR_CONSTRAINED & mode: 69cdf0e10cSrcweir ret = ret + "constrained " 70cdf0e10cSrcweir if PROP_ATTR_BOUND & mode: 71cdf0e10cSrcweir ret = ret + "bound " 72cdf0e10cSrcweir if PROP_ATTR_MAYBEVOID & mode: 73cdf0e10cSrcweir ret = ret + "maybevoid " 74cdf0e10cSrcweir return ret.rstrip() 75*d912c6c5SPedro Giffuni 76cdf0e10cSrcweirdef inspect( obj , out ): 77cdf0e10cSrcweir if isinstance( obj, uno.Type ) or \ 78cdf0e10cSrcweir isinstance( obj, uno.Char ) or \ 79cdf0e10cSrcweir isinstance( obj, uno.Bool ) or \ 80cdf0e10cSrcweir isinstance( obj, uno.ByteSequence ) or \ 81cdf0e10cSrcweir isinstance( obj, uno.Enum ) or \ 82cdf0e10cSrcweir isinstance( obj, uno.Any ): 83cdf0e10cSrcweir out.write( str(obj) + "\n") 84cdf0e10cSrcweir return 85cdf0e10cSrcweir 86cdf0e10cSrcweir ctx = uno.getComponentContext() 87cdf0e10cSrcweir introspection = \ 88cdf0e10cSrcweir ctx.ServiceManager.createInstanceWithContext( "com.sun.star.beans.Introspection", ctx ) 89cdf0e10cSrcweir 90cdf0e10cSrcweir out.write( "Supported services:\n" ) 91cdf0e10cSrcweir if hasattr( obj, "getSupportedServiceNames" ): 92cdf0e10cSrcweir names = obj.getSupportedServiceNames() 93cdf0e10cSrcweir for ii in names: 94cdf0e10cSrcweir out.write( " " + ii + "\n" ) 95cdf0e10cSrcweir else: 96cdf0e10cSrcweir out.write( " unknown\n" ) 97cdf0e10cSrcweir 98cdf0e10cSrcweir out.write( "Interfaces:\n" ) 99cdf0e10cSrcweir if hasattr( obj, "getTypes" ): 100cdf0e10cSrcweir interfaces = obj.getTypes() 101cdf0e10cSrcweir for ii in interfaces: 102cdf0e10cSrcweir out.write( " " + ii.typeName + "\n" ) 103cdf0e10cSrcweir else: 104cdf0e10cSrcweir out.write( " unknown\n" ) 105*d912c6c5SPedro Giffuni 106cdf0e10cSrcweir access = introspection.inspect( obj ) 107cdf0e10cSrcweir methods = access.getMethods( METHOD_CONCEPT_ALL ) 108cdf0e10cSrcweir out.write( "Methods:\n" ) 109cdf0e10cSrcweir for ii in methods: 110cdf0e10cSrcweir out.write( " " + ii.ReturnType.Name + " " + ii.Name ) 111cdf0e10cSrcweir args = ii.ParameterTypes 112cdf0e10cSrcweir infos = ii.ParameterInfos 113cdf0e10cSrcweir out.write( "( " ) 114cdf0e10cSrcweir for i in range( 0, len( args ) ): 115cdf0e10cSrcweir if i > 0: 116cdf0e10cSrcweir out.write( ", " ) 117cdf0e10cSrcweir out.write( _mode_to_str( infos[i].aMode ) + " " + args[i].Name + " " + infos[i].aName ) 118cdf0e10cSrcweir out.write( " )\n" ) 119cdf0e10cSrcweir 120cdf0e10cSrcweir props = access.getProperties( PROPERTY_CONCEPT_ALL ) 121cdf0e10cSrcweir out.write ("Properties:\n" ) 122cdf0e10cSrcweir for ii in props: 123cdf0e10cSrcweir out.write( " ("+_propertymode_to_str( ii.Attributes ) + ") "+ii.Type.typeName+" "+ii.Name+ "\n" ) 124cdf0e10cSrcweir 125cdf0e10cSrcweirdef createSingleServiceFactory( clazz, implementationName, serviceNames ): 126cdf0e10cSrcweir return _FactoryHelper_( clazz, implementationName, serviceNames ) 127cdf0e10cSrcweir 128cdf0e10cSrcweirclass _ImplementationHelperEntry: 129*d912c6c5SPedro Giffuni def __init__(self, ctor,serviceNames): 130*d912c6c5SPedro Giffuni self.ctor = ctor 131*d912c6c5SPedro Giffuni self.serviceNames = serviceNames 132*d912c6c5SPedro Giffuni 133cdf0e10cSrcweirclass ImplementationHelper: 134*d912c6c5SPedro Giffuni def __init__(self): 135*d912c6c5SPedro Giffuni self.impls = {} 136*d912c6c5SPedro Giffuni 137*d912c6c5SPedro Giffuni def addImplementation( self, ctor, implementationName, serviceNames ): 138*d912c6c5SPedro Giffuni self.impls[implementationName] = _ImplementationHelperEntry(ctor,serviceNames) 139*d912c6c5SPedro Giffuni 140*d912c6c5SPedro Giffuni def writeRegistryInfo( self, regKey, smgr ): 141*d912c6c5SPedro Giffuni for i in list(self.impls.items()): 142*d912c6c5SPedro Giffuni keyName = "/"+ i[0] + "/UNO/SERVICES" 143*d912c6c5SPedro Giffuni key = regKey.createKey( keyName ) 144*d912c6c5SPedro Giffuni for serviceName in i[1].serviceNames: 145*d912c6c5SPedro Giffuni key.createKey( serviceName ) 146*d912c6c5SPedro Giffuni return 1 147*d912c6c5SPedro Giffuni 148*d912c6c5SPedro Giffuni def getComponentFactory( self, implementationName , regKey, smgr ): 149*d912c6c5SPedro Giffuni entry = self.impls.get( implementationName, None ) 150*d912c6c5SPedro Giffuni if entry == None: 151*d912c6c5SPedro Giffuni raise RuntimeException( implementationName + " is unknown" , None ) 152*d912c6c5SPedro Giffuni return createSingleServiceFactory( entry.ctor, implementationName, entry.serviceNames ) 153*d912c6c5SPedro Giffuni 154*d912c6c5SPedro Giffuni def getSupportedServiceNames( self, implementationName ): 155*d912c6c5SPedro Giffuni entry = self.impls.get( implementationName, None ) 156*d912c6c5SPedro Giffuni if entry == None: 157*d912c6c5SPedro Giffuni raise RuntimeException( implementationName + " is unknown" , None ) 158*d912c6c5SPedro Giffuni return entry.serviceNames 159*d912c6c5SPedro Giffuni 160*d912c6c5SPedro Giffuni def supportsService( self, implementationName, serviceName ): 161*d912c6c5SPedro Giffuni entry = self.impls.get( implementationName,None ) 162*d912c6c5SPedro Giffuni if entry == None: 163*d912c6c5SPedro Giffuni raise RuntimeException( implementationName + " is unknown", None ) 164*d912c6c5SPedro Giffuni return serviceName in entry.serviceNames 165*d912c6c5SPedro Giffuni 166*d912c6c5SPedro Giffuni 167cdf0e10cSrcweirclass ImplementationEntry: 168*d912c6c5SPedro Giffuni def __init__(self, implName, supportedServices, clazz ): 169*d912c6c5SPedro Giffuni self.implName = implName 170*d912c6c5SPedro Giffuni self.supportedServices = supportedServices 171*d912c6c5SPedro Giffuni self.clazz = clazz 172cdf0e10cSrcweir 173cdf0e10cSrcweirdef writeRegistryInfoHelper( smgr, regKey, seqEntries ): 174cdf0e10cSrcweir for entry in seqEntries: 175cdf0e10cSrcweir keyName = "/"+ entry.implName + "/UNO/SERVICES" 176*d912c6c5SPedro Giffuni key = regKey.createKey( keyName ) 177*d912c6c5SPedro Giffuni for serviceName in entry.supportedServices: 178*d912c6c5SPedro Giffuni key.createKey( serviceName ) 179cdf0e10cSrcweir 180cdf0e10cSrcweirdef systemPathToFileUrl( systemPath ): 181cdf0e10cSrcweir "returns a file-url for the given system path" 182cdf0e10cSrcweir return pyuno.systemPathToFileUrl( systemPath ) 183cdf0e10cSrcweir 184cdf0e10cSrcweirdef fileUrlToSystemPath( url ): 185cdf0e10cSrcweir "returns a system path (determined by the system, the python interpreter is running on)" 186cdf0e10cSrcweir return pyuno.fileUrlToSystemPath( url ) 187cdf0e10cSrcweir 188cdf0e10cSrcweirdef absolutize( path, relativeUrl ): 189cdf0e10cSrcweir "returns an absolute file url from the given urls" 190cdf0e10cSrcweir return pyuno.absolutize( path, relativeUrl ) 191*d912c6c5SPedro Giffuni 192cdf0e10cSrcweirdef getComponentFactoryHelper( implementationName, smgr, regKey, seqEntries ): 193cdf0e10cSrcweir for x in seqEntries: 194*d912c6c5SPedro Giffuni if x.implName == implementationName: 195*d912c6c5SPedro Giffuni return createSingleServiceFactory( x.clazz, implementationName, x.supportedServices ) 196cdf0e10cSrcweir 197cdf0e10cSrcweirdef addComponentsToContext( toBeExtendedContext, contextRuntime, componentUrls, loaderName ): 198cdf0e10cSrcweir smgr = contextRuntime.ServiceManager 199cdf0e10cSrcweir loader = smgr.createInstanceWithContext( loaderName, contextRuntime ) 200cdf0e10cSrcweir implReg = smgr.createInstanceWithContext( "com.sun.star.registry.ImplementationRegistration",contextRuntime) 201cdf0e10cSrcweir 202cdf0e10cSrcweir isWin = os.name == 'nt' or os.name == 'dos' 203cdf0e10cSrcweir isMac = sys.platform == 'darwin' 204cdf0e10cSrcweir # create a temporary registry 205cdf0e10cSrcweir for componentUrl in componentUrls: 206cdf0e10cSrcweir reg = smgr.createInstanceWithContext( "com.sun.star.registry.SimpleRegistry", contextRuntime ) 207*d912c6c5SPedro Giffuni reg.open( "", 0, 1 ) 208cdf0e10cSrcweir if not isWin and componentUrl.endswith( ".uno" ): # still allow platform independent naming 209cdf0e10cSrcweir if isMac: 210*d912c6c5SPedro Giffuni componentUrl = componentUrl + ".dylib" 211cdf0e10cSrcweir else: 212*d912c6c5SPedro Giffuni componentUrl = componentUrl + ".so" 213*d912c6c5SPedro Giffuni 214*d912c6c5SPedro Giffuni implReg.registerImplementation( loaderName,componentUrl, reg ) 215*d912c6c5SPedro Giffuni rootKey = reg.getRootKey() 216*d912c6c5SPedro Giffuni implementationKey = rootKey.openKey( "IMPLEMENTATIONS" ) 217*d912c6c5SPedro Giffuni implNames = implementationKey.getKeyNames() 218*d912c6c5SPedro Giffuni extSMGR = toBeExtendedContext.ServiceManager 219*d912c6c5SPedro Giffuni for x in implNames: 220*d912c6c5SPedro Giffuni fac = loader.activate( max(x.split("/")),"",componentUrl,rootKey) 221*d912c6c5SPedro Giffuni extSMGR.insert( fac ) 222*d912c6c5SPedro Giffuni reg.close() 223*d912c6c5SPedro Giffuni 224cdf0e10cSrcweir# never shrinks ! 225cdf0e10cSrcweir_g_typeTable = {} 226cdf0e10cSrcweirdef _unohelper_getHandle( self): 227*d912c6c5SPedro Giffuni ret = None 228*d912c6c5SPedro Giffuni if self.__class__ in _g_typeTable: 229*d912c6c5SPedro Giffuni ret = _g_typeTable[self.__class__] 230*d912c6c5SPedro Giffuni else: 231*d912c6c5SPedro Giffuni names = {} 232*d912c6c5SPedro Giffuni traverse = list(self.__class__.__bases__) 233*d912c6c5SPedro Giffuni while len( traverse ) > 0: 234*d912c6c5SPedro Giffuni item = traverse.pop() 235*d912c6c5SPedro Giffuni bases = item.__bases__ 236*d912c6c5SPedro Giffuni if uno.isInterface( item ): 237*d912c6c5SPedro Giffuni names[item.__pyunointerface__] = None 238*d912c6c5SPedro Giffuni elif len(bases) > 0: 239*d912c6c5SPedro Giffuni # the "else if", because we only need the most derived interface 240*d912c6c5SPedro Giffuni traverse = traverse + list(bases)# 241*d912c6c5SPedro Giffuni 242*d912c6c5SPedro Giffuni lst = list(names.keys()) 243*d912c6c5SPedro Giffuni types = [] 244*d912c6c5SPedro Giffuni for x in lst: 245*d912c6c5SPedro Giffuni t = uno.getTypeByName( x ) 246*d912c6c5SPedro Giffuni types.append( t ) 247*d912c6c5SPedro Giffuni 248*d912c6c5SPedro Giffuni ret = tuple(types) , uno.generateUuid() 249*d912c6c5SPedro Giffuni _g_typeTable[self.__class__] = ret 250*d912c6c5SPedro Giffuni return ret 251*d912c6c5SPedro Giffuni 252cdf0e10cSrcweirclass Base(XTypeProvider): 253*d912c6c5SPedro Giffuni def getTypes( self ): 254*d912c6c5SPedro Giffuni return _unohelper_getHandle( self )[0] 255*d912c6c5SPedro Giffuni def getImplementationId(self): 256*d912c6c5SPedro Giffuni return _unohelper_getHandle( self )[1] 257cdf0e10cSrcweir 258cdf0e10cSrcweirclass CurrentContext(XCurrentContext, Base ): 259cdf0e10cSrcweir """a current context implementation, which first does a lookup in the given 260cdf0e10cSrcweir hashmap and if the key cannot be found, it delegates to the predecessor 261cdf0e10cSrcweir if available 262cdf0e10cSrcweir """ 263cdf0e10cSrcweir def __init__( self, oldContext, hashMap ): 264cdf0e10cSrcweir self.hashMap = hashMap 265cdf0e10cSrcweir self.oldContext = oldContext 266cdf0e10cSrcweir 267cdf0e10cSrcweir def getValueByName( self, name ): 268cdf0e10cSrcweir if name in self.hashMap: 269cdf0e10cSrcweir return self.hashMap[name] 270cdf0e10cSrcweir elif self.oldContext != None: 271cdf0e10cSrcweir return self.oldContext.getValueByName( name ) 272cdf0e10cSrcweir else: 273cdf0e10cSrcweir return None 274*d912c6c5SPedro Giffuni 275cdf0e10cSrcweir# ------------------------------------------------- 276cdf0e10cSrcweir# implementation details 277cdf0e10cSrcweir# ------------------------------------------------- 278cdf0e10cSrcweirclass _FactoryHelper_( XSingleComponentFactory, XServiceInfo, Base ): 279*d912c6c5SPedro Giffuni def __init__( self, clazz, implementationName, serviceNames ): 280*d912c6c5SPedro Giffuni self.clazz = clazz 281*d912c6c5SPedro Giffuni self.implementationName = implementationName 282*d912c6c5SPedro Giffuni self.serviceNames = serviceNames 283*d912c6c5SPedro Giffuni 284*d912c6c5SPedro Giffuni def getImplementationName( self ): 285*d912c6c5SPedro Giffuni return self.implementationName 286*d912c6c5SPedro Giffuni 287*d912c6c5SPedro Giffuni def supportsService( self, ServiceName ): 288*d912c6c5SPedro Giffuni return ServiceName in self.serviceNames 289*d912c6c5SPedro Giffuni 290*d912c6c5SPedro Giffuni def getSupportedServiceNames( self ): 291*d912c6c5SPedro Giffuni return self.serviceNames 292*d912c6c5SPedro Giffuni 293*d912c6c5SPedro Giffuni def createInstanceWithContext( self, context ): 294*d912c6c5SPedro Giffuni return self.clazz( context ) 295*d912c6c5SPedro Giffuni 296*d912c6c5SPedro Giffuni def createInstanceWithArgumentsAndContext( self, args, context ): 297*d912c6c5SPedro Giffuni return self.clazz( context, *args ) 298