nss: upgrade to release 3.73
[LibreOffice.git] / pyuno / source / loader / pythonloader.py
blob5b824a3c26a109a54e3404bbb55341e5dc6d299a
1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 # This file incorporates work covered by the following license notice:
11 # Licensed to the Apache Software Foundation (ASF) under one or more
12 # contributor license agreements. See the NOTICE file distributed
13 # with this work for additional information regarding copyright
14 # ownership. The ASF licenses this file to you under the Apache
15 # License, Version 2.0 (the "License"); you may not use this file
16 # except in compliance with the License. You may obtain a copy of
17 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 import uno
20 import unohelper
21 import sys
22 import types
23 import os
24 from com.sun.star.uno import Exception,RuntimeException
25 from com.sun.star.loader import XImplementationLoader
26 from com.sun.star.lang import XServiceInfo
28 MODULE_PROTOCOL = "vnd.openoffice.pymodule:"
29 DEBUG = 0
31 g_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader !
32 g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader !
34 def splitUrl( url ):
35 nColon = url.find( ":" )
36 if -1 == nColon:
37 raise RuntimeException( "PythonLoader: No protocol in url " + url, None )
38 return url[0:nColon], url[nColon+1:len(url)]
40 g_loadedComponents = {}
41 def checkForPythonPathBesideComponent( url ):
42 path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" );
43 if DEBUG == 1:
44 print(b"checking for existence of " + encfile( path ))
45 if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path:
46 if DEBUG == 1:
47 print(b"adding " + encfile( path ) + b" to sys.path")
48 sys.path.append( path )
50 path = unohelper.fileUrlToSystemPath( url+"/pythonpath" );
51 if 1 == os.access( encfile( path ), os.F_OK) and not path in sys.path:
52 if DEBUG == 1:
53 print(b"adding " + encfile( path ) + b" to sys.path")
54 sys.path.append( path )
56 def encfile(uni):
57 return uni.encode( sys.getfilesystemencoding())
59 class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ):
60 def __init__(self, ctx ):
61 if DEBUG:
62 print("pythonloader.Loader ctor")
63 self.ctx = ctx
65 def getModuleFromUrl( self, url ):
66 if DEBUG:
67 print("pythonloader: interpreting url " + url)
68 protocol, dependent = splitUrl( url )
69 if "vnd.sun.star.expand" == protocol:
70 exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" )
71 url = exp.expandMacros(dependent)
72 protocol,dependent = splitUrl( url )
74 if DEBUG:
75 print("pythonloader: after expansion " + protocol + ":" + dependent)
77 try:
78 if "file" == protocol:
79 # remove \..\ sequence, which may be useful e.g. in the build env
80 url = unohelper.absolutize( url, url )
82 # did we load the module already ?
83 mod = g_loadedComponents.get( url )
84 if not mod:
85 mod = types.ModuleType("uno_component")
87 # check for pythonpath.zip beside .py files
88 checkForPythonPathBesideComponent( url[0:url.rfind('/')] )
90 # read the file
91 filename = unohelper.fileUrlToSystemPath( url )
93 fileHandle = open( filename, encoding='utf_8' )
94 src = fileHandle.read().replace("\r","")
95 if not src.endswith( "\n" ):
96 src = src + "\n"
98 # compile and execute the module
99 codeobject = compile( src, encfile(filename), "exec" )
100 mod.__file__ = filename
101 exec(codeobject, mod.__dict__)
102 g_loadedComponents[url] = mod
103 return mod
104 elif "vnd.openoffice.pymodule" == protocol:
105 nSlash = dependent.rfind('/')
106 if -1 != nSlash:
107 path = unohelper.fileUrlToSystemPath( dependent[0:nSlash] )
108 dependent = dependent[nSlash+1:len(dependent)]
109 if not path in sys.path:
110 sys.path.append( path )
111 mod = __import__( dependent )
112 path_component, dot, rest = dependent.partition('.')
113 while dot == '.':
114 path_component, dot, rest = rest.partition('.')
115 mod = getattr(mod, path_component)
116 return mod
117 else:
118 if DEBUG:
119 print("Unknown protocol '" + protocol + "'");
120 raise RuntimeException( "PythonLoader: Unknown protocol " +
121 protocol + " in url " +url, self )
122 except Exception as e:
123 if DEBUG:
124 print ("Python import exception " + str(type(e)) +
125 " message " + str(e) + " args " + str(e.args));
126 raise RuntimeException( "Couldn't load " + url + " for reason " + str(e), None )
127 return None
129 def activate( self, implementationName, dummy, locationUrl, regKey ):
130 if DEBUG:
131 print("pythonloader.Loader.activate")
133 mod = self.getModuleFromUrl( locationUrl )
134 implHelper = mod.__dict__.get( "g_ImplementationHelper" , None )
135 if DEBUG:
136 print ("Fetched ImplHelper as " + str(implHelper))
137 if implHelper is None:
138 return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey )
139 else:
140 return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager)
142 def writeRegistryInfo( self, regKey, dummy, locationUrl ):
143 if DEBUG:
144 print( "pythonloader.Loader.writeRegistryInfo" )
146 mod = self.getModuleFromUrl( locationUrl )
147 implHelper = mod.__dict__.get( "g_ImplementationHelper" , None )
148 if implHelper is None:
149 return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey )
150 else:
151 return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager )
153 def getImplementationName( self ):
154 return g_implementationName
156 def supportsService( self, ServiceName ):
157 return ServiceName in self.getSupportedServiceNames()
159 def getSupportedServiceNames( self ):
160 return g_supportedServices
162 # vim: set shiftwidth=4 softtabstop=4 expandtab: