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