| #************************************************************** |
| # |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| # |
| #************************************************************** |
| import uno |
| import unohelper |
| import sys |
| import imp |
| import os |
| from com.sun.star.uno import Exception,RuntimeException |
| from com.sun.star.loader import XImplementationLoader |
| from com.sun.star.lang import XServiceInfo |
| |
| MODULE_PROTOCOL = "vnd.openoffice.pymodule:" |
| DEBUG = 0 |
| |
| g_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader ! |
| g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! |
| |
| def splitUrl( url ): |
| nColon = url.find( ":" ) |
| if -1 == nColon: |
| raise RuntimeException( "PythonLoader: No protocol in url " + url, None ) |
| return url[0:nColon], url[nColon+1:len(url)] |
| |
| g_loadedComponents = {} |
| def checkForPythonPathBesideComponent( url ): |
| path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); |
| if DEBUG == 1: |
| print("checking for existence of " + encfile( path )) |
| if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: |
| if DEBUG == 1: |
| print("adding " + encfile( path ) + " to sys.path") |
| sys.path.append( path ) |
| |
| path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); |
| if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: |
| if DEBUG == 1: |
| print("adding " + encfile( path ) + " to sys.path") |
| sys.path.append( path ) |
| |
| def encfile(uni): |
| return uni.encode( sys.getfilesystemencoding()) |
| |
| class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): |
| def __init__(self, ctx ): |
| if DEBUG: |
| print("pythonloader.Loader ctor") |
| self.ctx = ctx |
| |
| def getModuleFromUrl( self, url ): |
| if DEBUG: |
| print("pythonloader: interpreting url " +url) |
| protocol, dependent = splitUrl( url ) |
| if "vnd.sun.star.expand" == protocol: |
| exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" ) |
| url = exp.expandMacros(dependent) |
| protocol,dependent = splitUrl( url ) |
| |
| if DEBUG: |
| print("pythonloader: after expansion " +protocol +":" + dependent) |
| |
| try: |
| if "file" == protocol: |
| # remove \..\ sequence, which may be useful e.g. in the build env |
| url = unohelper.absolutize( url, url ) |
| |
| # did we load the module already ? |
| mod = g_loadedComponents.get( url ) |
| if not mod: |
| mod = imp.new_module("uno_component") |
| |
| # check for pythonpath.zip beside .py files |
| checkForPythonPathBesideComponent( url[0:url.rfind('/')] ) |
| |
| # read the file |
| filename = unohelper.fileUrlToSystemPath( url ) |
| fileHandle = file( filename ) |
| src = fileHandle.read().replace("\r","") |
| if not src.endswith( "\n" ): |
| src = src + "\n" |
| |
| # compile and execute the module |
| codeobject = compile( src, encfile(filename), "exec" ) |
| exec(codeobject, mod.__dict__) |
| mod.__file__ = encfile(filename) |
| g_loadedComponents[url] = mod |
| return mod |
| elif "vnd.openoffice.pymodule" == protocol: |
| return __import__( dependent ) |
| else: |
| raise RuntimeException( "PythonLoader: Unknown protocol " + |
| protocol + " in url " +url, self ) |
| except ImportError as e: |
| raise RuntimeException( "Couldn't load "+url+ " for reason "+str(e), None) |
| return None |
| |
| def activate( self, implementationName, dummy, locationUrl, regKey ): |
| if DEBUG: |
| print("pythonloader.Loader.activate") |
| |
| mod = self.getModuleFromUrl( locationUrl ) |
| implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) |
| if implHelper == None: |
| return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) |
| else: |
| return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) |
| |
| def writeRegistryInfo( self, regKey, dummy, locationUrl ): |
| if DEBUG: |
| print("pythonloader.Loader.writeRegistryInfo") |
| |
| mod = self.getModuleFromUrl( locationUrl ) |
| implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) |
| if implHelper == None: |
| return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) |
| else: |
| return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) |
| |
| def getImplementationName( self ): |
| return g_implementationName |
| |
| def supportsService( self, ServiceName ): |
| return ServiceName in self.serviceNames |
| |
| def getSupportedServiceNames( self ): |
| return g_supportedServices |