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