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 .
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
):
46 if mode
== PARAM_MODE_INOUT
:
48 elif mode
== PARAM_MODE_OUT
:
50 elif mode
== PARAM_MODE_IN
:
54 def _propertymode_to_str( mode
):
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
:
70 if PROP_ATTR_MAYBEVOID
& mode
:
71 ret
= ret
+ "maybevoid "
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")
84 ctx
= uno
.getComponentContext()
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()
92 out
.write( " " + ii
+ "\n" )
94 out
.write( " unknown\n" )
96 out
.write( "Interfaces:\n" )
97 if hasattr( obj
, "getTypes" ):
98 interfaces
= obj
.getTypes()
100 out
.write( " " + ii
.typeName
+ "\n" )
102 out
.write( " unknown\n" )
104 access
= introspection
.inspect( obj
)
105 methods
= access
.getMethods( METHOD_CONCEPT_ALL
)
106 out
.write( "Methods:\n" )
108 out
.write( " " + ii
.ReturnType
.Name
+ " " + ii
.Name
)
109 args
= ii
.ParameterTypes
110 infos
= ii
.ParameterInfos
112 for i
in range( 0, len( args
) ):
115 out
.write( _mode_to_str( infos
[i
].aMode
) + " " + args
[i
].Name
+ " " + infos
[i
].aName
)
118 props
= access
.getProperties( PROPERTY_CONCEPT_ALL
)
119 out
.write ("Properties:\n" )
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
):
129 self
.serviceNames
= serviceNames
131 class ImplementationHelper
:
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
)
146 def getComponentFactory( self
, implementationName
, regKey
, smgr
):
147 entry
= self
.impls
.get( implementationName
, 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 )
155 raise RuntimeException( implementationName
+ " is unknown" , None )
156 return entry
.serviceNames
158 def supportsService( self
, implementationName
, serviceName
):
159 entry
= self
.impls
.get( implementationName
,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
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
):
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
)
206 if not isWin
and componentUrl
.endswith( ".uno" ): # still allow platform independent naming
208 componentUrl
= componentUrl
+ ".dylib"
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
218 fac
= loader
.activate( max(x
.split("/")),"",componentUrl
,rootKey
)
219 extSMGR
.insert( fac
)
224 def _unohelper_getHandle( self
):
226 if self
.__class
__ in _g_typeTable
:
227 ret
= _g_typeTable
[self
.__class
__]
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
237 # the "else if", because we only need the most derived interface
238 traverse
= traverse
+ list(bases
)#
240 lst
= list(names
.keys())
243 t
= uno
.getTypeByName( x
)
247 _g_typeTable
[self
.__class
__] = ret
250 class Base(XTypeProvider
):
251 def getTypes( self
):
252 return _unohelper_getHandle( self
)
253 def getImplementationId(self
):
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
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
)
273 # -------------------------------------------------
274 # implementation details
275 # -------------------------------------------------
276 class _FactoryHelper_( XSingleComponentFactory
, XServiceInfo
, Base
):
277 def __init__( self
, clazz
, implementationName
, serviceNames
):
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: