| #************************************************************** |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| #************************************************************** |
| 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 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 == 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 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) , 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 ) |