1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20#************************************************************** 21import uno 22import unohelper 23import sys 24import imp 25import os 26from com.sun.star.uno import Exception,RuntimeException 27from com.sun.star.loader import XImplementationLoader 28from com.sun.star.lang import XServiceInfo 29 30MODULE_PROTOCOL = "vnd.openoffice.pymodule:" 31DEBUG = 0 32 33g_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader ! 34g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! 35 36def splitUrl( url ): 37 nColon = url.find( ":" ) 38 if -1 == nColon: 39 raise RuntimeException( "PythonLoader: No protocol in url " + url, None ) 40 return url[0:nColon], url[nColon+1:len(url)] 41 42g_loadedComponents = {} 43def checkForPythonPathBesideComponent( url ): 44 path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); 45 if DEBUG == 1: 46 print("checking for existence of " + encfile( path )) 47 if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: 48 if DEBUG == 1: 49 print("adding " + encfile( path ) + " to sys.path") 50 sys.path.append( path ) 51 52 path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); 53 if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: 54 if DEBUG == 1: 55 print("adding " + encfile( path ) + " to sys.path") 56 sys.path.append( path ) 57 58def encfile(uni): 59 return uni.encode( sys.getfilesystemencoding()) 60 61class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): 62 def __init__(self, ctx ): 63 if DEBUG: 64 print("pythonloader.Loader ctor") 65 self.ctx = ctx 66 67 def getModuleFromUrl( self, url ): 68 if DEBUG: 69 print("pythonloader: interpreting url " +url) 70 protocol, dependent = splitUrl( url ) 71 if "vnd.sun.star.expand" == protocol: 72 exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" ) 73 url = exp.expandMacros(dependent) 74 protocol,dependent = splitUrl( url ) 75 76 if DEBUG: 77 print("pythonloader: after expansion " +protocol +":" + dependent) 78 79 try: 80 if "file" == protocol: 81 # remove \..\ sequence, which may be useful e.g. in the build env 82 url = unohelper.absolutize( url, url ) 83 84 # did we load the module already ? 85 mod = g_loadedComponents.get( url ) 86 if not mod: 87 mod = imp.new_module("uno_component") 88 89 # check for pythonpath.zip beside .py files 90 checkForPythonPathBesideComponent( url[0:url.rfind('/')] ) 91 92 # read the file 93 filename = unohelper.fileUrlToSystemPath( url ) 94 fileHandle = file( filename ) 95 src = fileHandle.read().replace("\r","") 96 if not src.endswith( "\n" ): 97 src = src + "\n" 98 99 # compile and execute the module 100 codeobject = compile( src, encfile(filename), "exec" ) 101 exec(codeobject, mod.__dict__) 102 mod.__file__ = encfile(filename) 103 g_loadedComponents[url] = mod 104 return mod 105 elif "vnd.openoffice.pymodule" == protocol: 106 return __import__( dependent ) 107 else: 108 raise RuntimeException( "PythonLoader: Unknown protocol " + 109 protocol + " in url " +url, self ) 110 except ImportError as e: 111 raise RuntimeException( "Couldn't load "+url+ " for reason "+str(e), None) 112 return None 113 114 def activate( self, implementationName, dummy, locationUrl, regKey ): 115 if DEBUG: 116 print("pythonloader.Loader.activate") 117 118 mod = self.getModuleFromUrl( locationUrl ) 119 implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) 120 if implHelper == None: 121 return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) 122 else: 123 return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) 124 125 def writeRegistryInfo( self, regKey, dummy, locationUrl ): 126 if DEBUG: 127 print("pythonloader.Loader.writeRegistryInfo") 128 129 mod = self.getModuleFromUrl( locationUrl ) 130 implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) 131 if implHelper == None: 132 return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) 133 else: 134 return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) 135 136 def getImplementationName( self ): 137 return g_implementationName 138 139 def supportsService( self, ServiceName ): 140 return ServiceName in self.serviceNames 141 142 def getSupportedServiceNames( self ): 143 return g_supportedServices 144