xref: /aoo41x/main/pyuno/source/module/unohelper.py (revision d912c6c5)
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