1*cdf0e10cSrcweir#************************************************************************* 2*cdf0e10cSrcweir# 3*cdf0e10cSrcweir# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir# 5*cdf0e10cSrcweir# Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir# 7*cdf0e10cSrcweir# OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir# 9*cdf0e10cSrcweir# This file is part of OpenOffice.org. 10*cdf0e10cSrcweir# 11*cdf0e10cSrcweir# OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir# it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir# only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir# 15*cdf0e10cSrcweir# OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir# but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir# GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir# (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir# 21*cdf0e10cSrcweir# You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir# version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir# <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir# for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir# 26*cdf0e10cSrcweir#************************************************************************* 27*cdf0e10cSrcweirimport uno 28*cdf0e10cSrcweirimport unohelper 29*cdf0e10cSrcweirimport sys 30*cdf0e10cSrcweirimport imp 31*cdf0e10cSrcweirimport os 32*cdf0e10cSrcweirfrom com.sun.star.uno import Exception,RuntimeException 33*cdf0e10cSrcweirfrom com.sun.star.loader import XImplementationLoader 34*cdf0e10cSrcweirfrom com.sun.star.lang import XServiceInfo 35*cdf0e10cSrcweir 36*cdf0e10cSrcweirMODULE_PROTOCOL = "vnd.openoffice.pymodule:" 37*cdf0e10cSrcweirDEBUG = 0 38*cdf0e10cSrcweir 39*cdf0e10cSrcweirg_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader ! 40*cdf0e10cSrcweirg_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! 41*cdf0e10cSrcweir 42*cdf0e10cSrcweirdef splitUrl( url ): 43*cdf0e10cSrcweir nColon = url.find( ":" ) 44*cdf0e10cSrcweir if -1 == nColon: 45*cdf0e10cSrcweir raise RuntimeException( "PythonLoader: No protocol in url " + url, None ) 46*cdf0e10cSrcweir return url[0:nColon], url[nColon+1:len(url)] 47*cdf0e10cSrcweir 48*cdf0e10cSrcweirg_loadedComponents = {} 49*cdf0e10cSrcweirdef checkForPythonPathBesideComponent( url ): 50*cdf0e10cSrcweir path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); 51*cdf0e10cSrcweir if DEBUG == 1: 52*cdf0e10cSrcweir print "checking for existence of " + encfile( path ) 53*cdf0e10cSrcweir if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: 54*cdf0e10cSrcweir if DEBUG == 1: 55*cdf0e10cSrcweir print "adding " + encfile( path ) + " to sys.path" 56*cdf0e10cSrcweir sys.path.append( path ) 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); 59*cdf0e10cSrcweir if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path: 60*cdf0e10cSrcweir if DEBUG == 1: 61*cdf0e10cSrcweir print "adding " + encfile( path ) + " to sys.path" 62*cdf0e10cSrcweir sys.path.append( path ) 63*cdf0e10cSrcweir 64*cdf0e10cSrcweirdef encfile(uni): 65*cdf0e10cSrcweir return uni.encode( sys.getfilesystemencoding()) 66*cdf0e10cSrcweir 67*cdf0e10cSrcweirclass Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): 68*cdf0e10cSrcweir def __init__(self, ctx ): 69*cdf0e10cSrcweir if DEBUG: 70*cdf0e10cSrcweir print "pythonloader.Loader ctor" 71*cdf0e10cSrcweir self.ctx = ctx 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir def getModuleFromUrl( self, url ): 74*cdf0e10cSrcweir if DEBUG: 75*cdf0e10cSrcweir print "pythonloader: interpreting url " +url 76*cdf0e10cSrcweir protocol, dependent = splitUrl( url ) 77*cdf0e10cSrcweir if "vnd.sun.star.expand" == protocol: 78*cdf0e10cSrcweir exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" ) 79*cdf0e10cSrcweir url = exp.expandMacros(dependent) 80*cdf0e10cSrcweir protocol,dependent = splitUrl( url ) 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir if DEBUG: 83*cdf0e10cSrcweir print "pythonloader: after expansion " +protocol +":" + dependent 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir try: 86*cdf0e10cSrcweir if "file" == protocol: 87*cdf0e10cSrcweir # remove \..\ sequence, which may be useful e.g. in the build env 88*cdf0e10cSrcweir url = unohelper.absolutize( url, url ) 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir # did we load the module already ? 91*cdf0e10cSrcweir mod = g_loadedComponents.get( url ) 92*cdf0e10cSrcweir if not mod: 93*cdf0e10cSrcweir mod = imp.new_module("uno_component") 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir # check for pythonpath.zip beside .py files 96*cdf0e10cSrcweir checkForPythonPathBesideComponent( url[0:url.rfind('/')] ) 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir # read the file 99*cdf0e10cSrcweir filename = unohelper.fileUrlToSystemPath( url ) 100*cdf0e10cSrcweir fileHandle = file( filename ) 101*cdf0e10cSrcweir src = fileHandle.read().replace("\r","") 102*cdf0e10cSrcweir if not src.endswith( "\n" ): 103*cdf0e10cSrcweir src = src + "\n" 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir # compile and execute the module 106*cdf0e10cSrcweir codeobject = compile( src, encfile(filename), "exec" ) 107*cdf0e10cSrcweir exec codeobject in mod.__dict__ 108*cdf0e10cSrcweir mod.__file__ = encfile(filename) 109*cdf0e10cSrcweir g_loadedComponents[url] = mod 110*cdf0e10cSrcweir return mod 111*cdf0e10cSrcweir elif "vnd.openoffice.pymodule" == protocol: 112*cdf0e10cSrcweir return __import__( dependent ) 113*cdf0e10cSrcweir else: 114*cdf0e10cSrcweir raise RuntimeException( "PythonLoader: Unknown protocol " + 115*cdf0e10cSrcweir protocol + " in url " +url, self ) 116*cdf0e10cSrcweir except ImportError, e: 117*cdf0e10cSrcweir raise RuntimeException( "Couldn't load "+url+ " for reason "+str(e), None) 118*cdf0e10cSrcweir return None 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir def activate( self, implementationName, dummy, locationUrl, regKey ): 121*cdf0e10cSrcweir if DEBUG: 122*cdf0e10cSrcweir print "pythonloader.Loader.activate" 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir mod = self.getModuleFromUrl( locationUrl ) 125*cdf0e10cSrcweir implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) 126*cdf0e10cSrcweir if implHelper == None: 127*cdf0e10cSrcweir return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) 128*cdf0e10cSrcweir else: 129*cdf0e10cSrcweir return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir def writeRegistryInfo( self, regKey, dummy, locationUrl ): 132*cdf0e10cSrcweir if DEBUG: 133*cdf0e10cSrcweir print "pythonloader.Loader.writeRegistryInfo" 134*cdf0e10cSrcweir 135*cdf0e10cSrcweir mod = self.getModuleFromUrl( locationUrl ) 136*cdf0e10cSrcweir implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) 137*cdf0e10cSrcweir if implHelper == None: 138*cdf0e10cSrcweir return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) 139*cdf0e10cSrcweir else: 140*cdf0e10cSrcweir return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir def getImplementationName( self ): 143*cdf0e10cSrcweir return g_implementationName 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir def supportsService( self, ServiceName ): 146*cdf0e10cSrcweir return ServiceName in self.serviceNames 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir def getSupportedServiceNames( self ): 149*cdf0e10cSrcweir return g_supportedServices 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir 152