d0df704d8a
added python.path vm arg to startup script fixed infinite loop in unwrap() when displaying sequences of sequences git-svn-id: http://google-refine.googlecode.com/svn/trunk@509 7d457c2a-affb-35e4-300a-418c747d4874
139 lines
5.6 KiB
Python
139 lines
5.6 KiB
Python
###
|
|
#
|
|
# Copyright Alan Kennedy.
|
|
#
|
|
# You may contact the copyright holder at this uri:
|
|
#
|
|
# http://www.xhaus.com/contact/modjy
|
|
#
|
|
# The licence under which this code is released is the Apache License v2.0.
|
|
#
|
|
# The terms and conditions of this license are listed in a file contained
|
|
# in the distribution that also contained this file, under the name
|
|
# LICENSE.txt.
|
|
#
|
|
# You may also read a copy of the license at the following web address.
|
|
#
|
|
# http://modjy.xhaus.com/LICENSE.txt
|
|
#
|
|
###
|
|
|
|
import sys
|
|
import synchronize
|
|
|
|
from java.io import File
|
|
|
|
from modjy_exceptions import *
|
|
|
|
class modjy_publisher:
|
|
|
|
def init_publisher(self):
|
|
self.cache = None
|
|
if self.params['app_directory']:
|
|
self.app_directory = self.expand_relative_path(self.params['app_directory'])
|
|
else:
|
|
self.app_directory = self.servlet_context.getRealPath('/')
|
|
self.params['app_directory'] = self.app_directory
|
|
if not self.app_directory in sys.path:
|
|
sys.path.append(self.app_directory)
|
|
|
|
def map_uri(self, req, environ):
|
|
source_uri = '%s%s%s' % (self.app_directory, File.separator, self.params['app_filename'])
|
|
callable_name = self.params['app_callable_name']
|
|
if self.params['callable_query_name']:
|
|
query_string = req.getQueryString()
|
|
if query_string and '=' in query_string:
|
|
for name_val in query_string.split('&'):
|
|
name, value = name_val.split('=')
|
|
if name == self.params['callable_query_name']:
|
|
callable_name = value
|
|
return source_uri, callable_name
|
|
|
|
def get_app_object(self, req, environ):
|
|
environ["SCRIPT_NAME"] = "%s%s" % (req.getContextPath(), req.getServletPath())
|
|
path_info = req.getPathInfo() or ""
|
|
environ["PATH_INFO"] = path_info
|
|
environ["PATH_TRANSLATED"] = File(self.app_directory, path_info).getPath()
|
|
|
|
if self.params['app_import_name'] is not None:
|
|
return self.get_app_object_importable(self.params['app_import_name'])
|
|
else:
|
|
if self.cache is None:
|
|
self.cache = {}
|
|
return self.get_app_object_old_style(req, environ)
|
|
|
|
get_app_object = synchronize.make_synchronized(get_app_object)
|
|
|
|
def get_app_object_importable(self, importable_name):
|
|
self.log.debug("Attempting to import application callable '%s'\n" % (importable_name, ))
|
|
# Under the importable mechanism, the cache contains a single object
|
|
if self.cache is None:
|
|
application, instantiable, method_name = self.load_importable(importable_name.strip())
|
|
if instantiable and self.params['cache_callables']:
|
|
application = application()
|
|
self.cache = application, instantiable, method_name
|
|
application, instantiable, method_name = self.cache
|
|
self.log.debug("Application is " + str(application))
|
|
if instantiable and not self.params['cache_callables']:
|
|
application = application()
|
|
self.log.debug("Instantiated application is " + str(application))
|
|
if method_name is not None:
|
|
if not hasattr(application, method_name):
|
|
self.log.fatal("Attribute error application callable '%s' as no method '%s'" % (application, method_name))
|
|
self.raise_exc(ApplicationNotFound, "Attribute error application callable '%s' as no method '%s'" % (application, method_name))
|
|
application = getattr(application, method_name)
|
|
self.log.debug("Application method is " + str(application))
|
|
return application
|
|
|
|
def load_importable(self, name):
|
|
try:
|
|
instantiable = False ; method_name = None
|
|
importable_name = name
|
|
if name.find('()') != -1:
|
|
instantiable = True
|
|
importable_name, method_name = name.split('()')
|
|
if method_name.startswith('.'):
|
|
method_name = method_name[1:]
|
|
if not method_name:
|
|
method_name = None
|
|
module_path, from_name = importable_name.rsplit('.', 1)
|
|
imported = __import__(module_path, globals(), locals(), [from_name])
|
|
imported = getattr(imported, from_name)
|
|
return imported, instantiable, method_name
|
|
except (ImportError, AttributeError), aix:
|
|
self.log.fatal("Import error import application callable '%s': %s\n" % (name, str(aix)))
|
|
self.raise_exc(ApplicationNotFound, "Failed to import app callable '%s': %s" % (name, str(aix)))
|
|
|
|
def get_app_object_old_style(self, req, environ):
|
|
source_uri, callable_name = self.map_uri(req, environ)
|
|
source_filename = source_uri
|
|
if not self.params['cache_callables']:
|
|
self.log.debug("Caching of callables disabled")
|
|
return self.load_object(source_filename, callable_name)
|
|
if not self.cache.has_key( (source_filename, callable_name) ):
|
|
self.log.debug("Callable object not in cache: %s#%s" % (source_filename, callable_name) )
|
|
return self.load_object(source_filename, callable_name)
|
|
app_callable, last_mod = self.cache.get( (source_filename, callable_name) )
|
|
self.log.debug("Callable object was in cache: %s#%s" % (source_filename, callable_name) )
|
|
if self.params['reload_on_mod']:
|
|
f = File(source_filename)
|
|
if f.lastModified() > last_mod:
|
|
self.log.info("Source file '%s' has been modified: reloading" % source_filename)
|
|
return self.load_object(source_filename, callable_name)
|
|
return app_callable
|
|
|
|
def load_object(self, path, callable_name):
|
|
try:
|
|
app_ns = {} ; execfile(path, app_ns)
|
|
app_callable = app_ns[callable_name]
|
|
f = File(path)
|
|
self.cache[ (path, callable_name) ] = (app_callable, f.lastModified())
|
|
return app_callable
|
|
except IOError, ioe:
|
|
self.raise_exc(ApplicationNotFound, "Application filename not found: %s" % path)
|
|
except KeyError, k:
|
|
self.raise_exc(NoCallable, "No callable named '%s' in %s" % (callable_name, path))
|
|
except Exception, x:
|
|
self.raise_exc(NoCallable, "Error loading jython callable '%s': %s" % (callable_name, str(x)) )
|
|
|