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