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