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