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