Update ooo320-m1
[ooovba.git] / pyuno / source / module / unohelper.py
blobd2d50ab8229138c076ce37828813f7bb41cbd9c1
1 #*************************************************************************
3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 #
5 # Copyright 2008 by Sun Microsystems, Inc.
7 # OpenOffice.org - a multi-platform office productivity suite
9 # $RCSfile: unohelper.py,v $
11 # $Revision: 1.7 $
13 # This file is part of OpenOffice.org.
15 # OpenOffice.org is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU Lesser General Public License version 3
17 # only, as published by the Free Software Foundation.
19 # OpenOffice.org is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU Lesser General Public License version 3 for more details
23 # (a copy is included in the LICENSE file that accompanied this code).
25 # You should have received a copy of the GNU Lesser General Public License
26 # version 3 along with OpenOffice.org. If not, see
27 # <http://www.openoffice.org/license.html>
28 # for a copy of the LGPLv3 License.
30 #*************************************************************************
31 import uno
32 import pyuno
33 import os
34 import sys
36 from com.sun.star.lang import XTypeProvider, XSingleComponentFactory, XServiceInfo
37 from com.sun.star.uno import RuntimeException, XCurrentContext
38 from com.sun.star.beans.MethodConcept import ALL as METHOD_CONCEPT_ALL
39 from com.sun.star.beans.PropertyConcept import ALL as PROPERTY_CONCEPT_ALL
41 from com.sun.star.reflection.ParamMode import \
42 IN as PARAM_MODE_IN, \
43 OUT as PARAM_MODE_OUT, \
44 INOUT as PARAM_MODE_INOUT
46 from com.sun.star.beans.PropertyAttribute import \
47 MAYBEVOID as PROP_ATTR_MAYBEVOID, \
48 BOUND as PROP_ATTR_BOUND, \
49 CONSTRAINED as PROP_ATTR_CONSTRAINED, \
50 TRANSIENT as PROP_ATTR_TRANSIENT, \
51 READONLY as PROP_ATTR_READONLY, \
52 MAYBEAMBIGUOUS as PROP_ATTR_MAYBEAMBIGUOUS, \
53 MAYBEDEFAULT as PROP_ATTR_MAYBEDEFAULT, \
54 REMOVEABLE as PROP_ATTR_REMOVEABLE
56 def _mode_to_str( mode ):
57 ret = "[]"
58 if mode == PARAM_MODE_INOUT:
59 ret = "[inout]"
60 elif mode == PARAM_MODE_OUT:
61 ret = "[out]"
62 elif mode == PARAM_MODE_IN:
63 ret = "[in]"
64 return ret
66 def _propertymode_to_str( mode ):
67 ret = ""
68 if PROP_ATTR_REMOVEABLE & mode:
69 ret = ret + "removeable "
70 if PROP_ATTR_MAYBEDEFAULT & mode:
71 ret = ret + "maybedefault "
72 if PROP_ATTR_MAYBEAMBIGUOUS & mode:
73 ret = ret + "maybeambigous "
74 if PROP_ATTR_READONLY & mode:
75 ret = ret + "readonly "
76 if PROP_ATTR_TRANSIENT & mode:
77 ret = ret + "tranient "
78 if PROP_ATTR_CONSTRAINED & mode:
79 ret = ret + "constrained "
80 if PROP_ATTR_BOUND & mode:
81 ret = ret + "bound "
82 if PROP_ATTR_MAYBEVOID & mode:
83 ret = ret + "maybevoid "
84 return ret.rstrip()
86 def inspect( obj , out ):
87 if isinstance( obj, uno.Type ) or \
88 isinstance( obj, uno.Char ) or \
89 isinstance( obj, uno.Bool ) or \
90 isinstance( obj, uno.ByteSequence ) or \
91 isinstance( obj, uno.Enum ) or \
92 isinstance( obj, uno.Any ):
93 out.write( str(obj) + "\n")
94 return
96 ctx = uno.getComponentContext()
97 introspection = \
98 ctx.ServiceManager.createInstanceWithContext( "com.sun.star.beans.Introspection", ctx )
100 out.write( "Supported services:\n" )
101 if hasattr( obj, "getSupportedServiceNames" ):
102 names = obj.getSupportedServiceNames()
103 for ii in names:
104 out.write( " " + ii + "\n" )
105 else:
106 out.write( " unknown\n" )
108 out.write( "Interfaces:\n" )
109 if hasattr( obj, "getTypes" ):
110 interfaces = obj.getTypes()
111 for ii in interfaces:
112 out.write( " " + ii.typeName + "\n" )
113 else:
114 out.write( " unknown\n" )
116 access = introspection.inspect( obj )
117 methods = access.getMethods( METHOD_CONCEPT_ALL )
118 out.write( "Methods:\n" )
119 for ii in methods:
120 out.write( " " + ii.ReturnType.Name + " " + ii.Name )
121 args = ii.ParameterTypes
122 infos = ii.ParameterInfos
123 out.write( "( " )
124 for i in range( 0, len( args ) ):
125 if i > 0:
126 out.write( ", " )
127 out.write( _mode_to_str( infos[i].aMode ) + " " + args[i].Name + " " + infos[i].aName )
128 out.write( " )\n" )
130 props = access.getProperties( PROPERTY_CONCEPT_ALL )
131 out.write ("Properties:\n" )
132 for ii in props:
133 out.write( " ("+_propertymode_to_str( ii.Attributes ) + ") "+ii.Type.typeName+" "+ii.Name+ "\n" )
135 def createSingleServiceFactory( clazz, implementationName, serviceNames ):
136 return _FactoryHelper_( clazz, implementationName, serviceNames )
138 class _ImplementationHelperEntry:
139 def __init__(self, ctor,serviceNames):
140 self.ctor = ctor
141 self.serviceNames = serviceNames
143 class ImplementationHelper:
144 def __init__(self):
145 self.impls = {}
147 def addImplementation( self, ctor, implementationName, serviceNames ):
148 self.impls[implementationName] = _ImplementationHelperEntry(ctor,serviceNames)
150 def writeRegistryInfo( self, regKey, smgr ):
151 for i in self.impls.items():
152 keyName = "/"+ i[0] + "/UNO/SERVICES"
153 key = regKey.createKey( keyName )
154 for serviceName in i[1].serviceNames:
155 key.createKey( serviceName )
156 return 1
158 def getComponentFactory( self, implementationName , regKey, smgr ):
159 entry = self.impls.get( implementationName, None )
160 if entry == None:
161 raise RuntimeException( implementationName + " is unknown" , None )
162 return createSingleServiceFactory( entry.ctor, implementationName, entry.serviceNames )
164 def getSupportedServiceNames( self, implementationName ):
165 entry = self.impls.get( implementationName, None )
166 if entry == None:
167 raise RuntimeException( implementationName + " is unknown" , None )
168 return entry.serviceNames
170 def supportsService( self, implementationName, serviceName ):
171 entry = self.impls.get( implementationName,None )
172 if entry == None:
173 raise RuntimeException( implementationName + " is unknown", None )
174 return serviceName in entry.serviceNames
177 class ImplementationEntry:
178 def __init__(self, implName, supportedServices, clazz ):
179 self.implName = implName
180 self.supportedServices = supportedServices
181 self.clazz = clazz
183 def writeRegistryInfoHelper( smgr, regKey, seqEntries ):
184 for entry in seqEntries:
185 keyName = "/"+ entry.implName + "/UNO/SERVICES"
186 key = regKey.createKey( keyName )
187 for serviceName in entry.supportedServices:
188 key.createKey( serviceName )
190 def systemPathToFileUrl( systemPath ):
191 "returns a file-url for the given system path"
192 return pyuno.systemPathToFileUrl( systemPath )
194 def fileUrlToSystemPath( url ):
195 "returns a system path (determined by the system, the python interpreter is running on)"
196 return pyuno.fileUrlToSystemPath( url )
198 def absolutize( path, relativeUrl ):
199 "returns an absolute file url from the given urls"
200 return pyuno.absolutize( path, relativeUrl )
202 def getComponentFactoryHelper( implementationName, smgr, regKey, seqEntries ):
203 for x in seqEntries:
204 if x.implName == implementationName:
205 return createSingleServiceFactory( x.clazz, implementationName, x.supportedServices )
207 def addComponentsToContext( toBeExtendedContext, contextRuntime, componentUrls, loaderName ):
208 smgr = contextRuntime.ServiceManager
209 loader = smgr.createInstanceWithContext( loaderName, contextRuntime )
210 implReg = smgr.createInstanceWithContext( "com.sun.star.registry.ImplementationRegistration",contextRuntime)
212 isWin = os.name == 'nt' or os.name == 'dos'
213 isMac = sys.platform == 'darwin'
214 # create a temporary registry
215 for componentUrl in componentUrls:
216 reg = smgr.createInstanceWithContext( "com.sun.star.registry.SimpleRegistry", contextRuntime )
217 reg.open( "", 0, 1 )
218 if not isWin and componentUrl.endswith( ".uno" ): # still allow platform independent naming
219 if isMac:
220 componentUrl = componentUrl + ".dylib"
221 else:
222 componentUrl = componentUrl + ".so"
224 implReg.registerImplementation( loaderName,componentUrl, reg )
225 rootKey = reg.getRootKey()
226 implementationKey = rootKey.openKey( "IMPLEMENTATIONS" )
227 implNames = implementationKey.getKeyNames()
228 extSMGR = toBeExtendedContext.ServiceManager
229 for x in implNames:
230 fac = loader.activate( max(x.split("/")),"",componentUrl,rootKey)
231 extSMGR.insert( fac )
232 reg.close()
234 # never shrinks !
235 _g_typeTable = {}
236 def _unohelper_getHandle( self):
237 ret = None
238 if _g_typeTable.has_key( self.__class__ ):
239 ret = _g_typeTable[self.__class__]
240 else:
241 names = {}
242 traverse = list(self.__class__.__bases__)
243 while len( traverse ) > 0:
244 item = traverse.pop()
245 bases = item.__bases__
246 if uno.isInterface( item ):
247 names[item.__pyunointerface__] = None
248 elif len(bases) > 0:
249 # the "else if", because we only need the most derived interface
250 traverse = traverse + list(bases)#
252 lst = names.keys()
253 types = []
254 for x in lst:
255 t = uno.getTypeByName( x )
256 types.append( t )
258 ret = tuple(types) , uno.generateUuid()
259 _g_typeTable[self.__class__] = ret
260 return ret
262 class Base(XTypeProvider):
263 def getTypes( self ):
264 return _unohelper_getHandle( self )[0]
265 def getImplementationId(self):
266 return _unohelper_getHandle( self )[1]
268 class CurrentContext(XCurrentContext, Base ):
269 """a current context implementation, which first does a lookup in the given
270 hashmap and if the key cannot be found, it delegates to the predecessor
271 if available
273 def __init__( self, oldContext, hashMap ):
274 self.hashMap = hashMap
275 self.oldContext = oldContext
277 def getValueByName( self, name ):
278 if name in self.hashMap:
279 return self.hashMap[name]
280 elif self.oldContext != None:
281 return self.oldContext.getValueByName( name )
282 else:
283 return None
285 # -------------------------------------------------
286 # implementation details
287 # -------------------------------------------------
288 class _FactoryHelper_( XSingleComponentFactory, XServiceInfo, Base ):
289 def __init__( self, clazz, implementationName, serviceNames ):
290 self.clazz = clazz
291 self.implementationName = implementationName
292 self.serviceNames = serviceNames
294 def getImplementationName( self ):
295 return self.implementationName
297 def supportsService( self, ServiceName ):
298 return ServiceName in self.serviceNames
300 def getSupportedServiceNames( self ):
301 return self.serviceNames
303 def createInstanceWithContext( self, context ):
304 return self.clazz( context )
306 def createInstanceWithArgumentsAndContext( self, args, context ):
307 return self.clazz( context, *args )