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 unohelper 29import sys 30import imp 31import os 32from com.sun.star.uno import Exception,RuntimeException 33from com.sun.star.loader import XImplementationLoader 34from com.sun.star.lang import XServiceInfo 35 36MODULE_PROTOCOL = "vnd.openoffice.pymodule:" 37DEBUG = 0 38 39g_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader ! 40g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! 41 42def splitUrl( url ): 43 nColon = url.find( ":" ) 44 if -1 == nColon: 45 raise RuntimeException( "PythonLoader: No protocol in url " + url, None ) 46 return url[0:nColon], url[nColon+1:len(url)] 47 48g_loadedComponents = {} 49def checkForPythonPathBesideComponent( url ): 50 path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); 51 if DEBUG == 1: 52 print "checking for existence of " + encfile( path ) 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 58 path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); 59 if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: 60 if DEBUG == 1: 61 print "adding " + encfile( path ) + " to sys.path" 62 sys.path.append( path ) 63 64def encfile(uni): 65 return uni.encode( sys.getfilesystemencoding()) 66 67class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): 68 def __init__(self, ctx ): 69 if DEBUG: 70 print "pythonloader.Loader ctor" 71 self.ctx = ctx 72 73 def getModuleFromUrl( self, url ): 74 if DEBUG: 75 print "pythonloader: interpreting url " +url 76 protocol, dependent = splitUrl( url ) 77 if "vnd.sun.star.expand" == protocol: 78 exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" ) 79 url = exp.expandMacros(dependent) 80 protocol,dependent = splitUrl( url ) 81 82 if DEBUG: 83 print "pythonloader: after expansion " +protocol +":" + dependent 84 85 try: 86 if "file" == protocol: 87 # remove \..\ sequence, which may be useful e.g. in the build env 88 url = unohelper.absolutize( url, url ) 89 90 # did we load the module already ? 91 mod = g_loadedComponents.get( url ) 92 if not mod: 93 mod = imp.new_module("uno_component") 94 95 # check for pythonpath.zip beside .py files 96 checkForPythonPathBesideComponent( url[0:url.rfind('/')] ) 97 98 # read the file 99 filename = unohelper.fileUrlToSystemPath( url ) 100 fileHandle = file( filename ) 101 src = fileHandle.read().replace("\r","") 102 if not src.endswith( "\n" ): 103 src = src + "\n" 104 105 # compile and execute the module 106 codeobject = compile( src, encfile(filename), "exec" ) 107 exec codeobject in mod.__dict__ 108 mod.__file__ = encfile(filename) 109 g_loadedComponents[url] = mod 110 return mod 111 elif "vnd.openoffice.pymodule" == protocol: 112 return __import__( dependent ) 113 else: 114 raise RuntimeException( "PythonLoader: Unknown protocol " + 115 protocol + " in url " +url, self ) 116 except ImportError, e: 117 raise RuntimeException( "Couldn't load "+url+ " for reason "+str(e), None) 118 return None 119 120 def activate( self, implementationName, dummy, locationUrl, regKey ): 121 if DEBUG: 122 print "pythonloader.Loader.activate" 123 124 mod = self.getModuleFromUrl( locationUrl ) 125 implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) 126 if implHelper == None: 127 return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) 128 else: 129 return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) 130 131 def writeRegistryInfo( self, regKey, dummy, locationUrl ): 132 if DEBUG: 133 print "pythonloader.Loader.writeRegistryInfo" 134 135 mod = self.getModuleFromUrl( locationUrl ) 136 implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) 137 if implHelper == None: 138 return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) 139 else: 140 return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) 141 142 def getImplementationName( self ): 143 return g_implementationName 144 145 def supportsService( self, ServiceName ): 146 return ServiceName in self.serviceNames 147 148 def getSupportedServiceNames( self ): 149 return g_supportedServices 150 151 152