|
From: <fwi...@us...> - 2008-12-12 15:47:03
|
Revision: 5751
http://jython.svn.sourceforge.net/jython/?rev=5751&view=rev
Author: fwierzbicki
Date: 2008-12-12 15:46:58 +0000 (Fri, 12 Dec 2008)
Log Message:
-----------
Dropping modjy code directly into Lib. Needed to move the code formerly in
modjy.py into __init__.py in order to have a toplevel modjy/ dir (current modjy
goes directly into a root namespace). Dropping
com/xhaus/modjy/ModjyServlet.java into Jython's src dir, keeping
com/xhaus/modjy packaging as requested by Alan Kennedy, the author of modjy.
Added Paths:
-----------
branches/modjy/Lib/modjy/
branches/modjy/Lib/modjy/__init__.py
branches/modjy/Lib/modjy/modjy_exceptions.py
branches/modjy/Lib/modjy/modjy_impl.py
branches/modjy/Lib/modjy/modjy_log.py
branches/modjy/Lib/modjy/modjy_params.py
branches/modjy/Lib/modjy/modjy_publish.py
branches/modjy/Lib/modjy/modjy_response.py
branches/modjy/Lib/modjy/modjy_write.py
branches/modjy/Lib/modjy/modjy_wsgi.py
branches/modjy/src/com/xhaus/
branches/modjy/src/com/xhaus/modjy/
branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java
Added: branches/modjy/Lib/modjy/__init__.py
===================================================================
--- branches/modjy/Lib/modjy/__init__.py (rev 0)
+++ branches/modjy/Lib/modjy/__init__.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,119 @@
+###
+#
+# Copyright 2004-2008 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
+#
+###
+
+__all__ = ['modjy', 'modjy_exceptions', 'modjy_impl', 'modjy_log', 'modjy_params', 'modjy_publish', 'modjy_response', 'modjy_write', 'modjy_wsgi',]
+
+import jarray
+import synchronize
+import sys
+import types
+
+sys.add_package("javax.servlet")
+sys.add_package("javax.servlet.http")
+sys.add_package("org.python.core")
+
+from modjy_exceptions import *
+from modjy_log import *
+from modjy_params import modjy_param_mgr, modjy_servlet_params
+from modjy_wsgi import modjy_wsgi
+from modjy_response import start_response_object
+from modjy_impl import modjy_impl
+from modjy_publish import modjy_publisher
+
+from javax.servlet.http import HttpServlet
+
+class modjy_servlet(HttpServlet, modjy_publisher, modjy_wsgi, modjy_impl):
+
+ def __init__(self):
+ HttpServlet.__init__(self)
+
+ def do_param(self, name, value):
+ if name[:3] == 'log':
+ getattr(self.log, "set_%s" % name)(value)
+ else:
+ self.params[name] = value
+
+ def get_params(self):
+ for pname in self.servlet_context.getInitParameterNames():
+ self.do_param(pname, self.servlet_context.getInitParameter(pname))
+ for pname in self.servlet.getInitParameterNames():
+ self.do_param(pname, self.servlet.getInitParameter(pname))
+
+ def init(self, delegator):
+ self.servlet = delegator
+ self.servlet_context = self.servlet.getServletContext()
+ self.servlet_config = self.servlet.getServletConfig()
+ self.log = modjy_logger(self.servlet_context)
+ self.params = modjy_param_mgr(modjy_servlet_params)
+ self.get_params()
+ self.init_impl()
+ self.init_publisher()
+ import modjy_exceptions
+ self.exc_handler = getattr(modjy_exceptions, '%s_handler' % self.params['exc_handler'])()
+
+ def service (self, req, resp):
+ wsgi_environ = {}
+ try:
+ self.dispatch_to_application(req, resp, wsgi_environ)
+ except ModjyException, mx:
+ self.log.error("Exception servicing request: %s" % str(mx))
+ typ, value, tb = sys.exc_info()[:]
+ self.exc_handler.handle(req, resp, wsgi_environ, mx, (typ, value, tb) )
+
+ def get_j2ee_ns(self, req, resp):
+ return {
+ 'servlet': self.servlet,
+ 'servlet_context': self.servlet_context,
+ 'servlet_config': self.servlet_config,
+ 'request': req,
+ 'response': resp,
+ }
+
+ def dispatch_to_application(self, req, resp, environ):
+ app_callable = self.get_app_object(req, environ)
+ self.set_wsgi_environment(req, resp, environ, self.params, self.get_j2ee_ns(req, resp))
+ response_callable = start_response_object(req, resp)
+ try:
+ app_return = self.call_application(app_callable, environ, response_callable)
+ if app_return is None:
+ raise ReturnNotIterable("Application returned None: must return an iterable")
+ self.deal_with_app_return(environ, response_callable, app_return)
+ except ModjyException, mx:
+ self.raise_exc(mx.__class__, str(mx))
+ except Exception, x:
+ self.raise_exc(ApplicationException, str(x))
+
+ def call_application(self, app_callable, environ, response_callable):
+ if self.params['multithread']:
+ return app_callable.__call__(environ, response_callable)
+ else:
+ return synchronize.apply_synchronized( \
+ app_callable, \
+ app_callable, \
+ (environ, response_callable))
+
+ def expand_relative_path(self, path):
+ if path.startswith("$"):
+ return self.servlet.getServletContext().getRealPath(path[1:])
+ return path
+
+ def raise_exc(self, exc_class, message):
+ self.log.error(message)
+ raise exc_class(message)
Added: branches/modjy/Lib/modjy/modjy_exceptions.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_exceptions.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_exceptions.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,91 @@
+###
+#
+# Copyright 2004-2008 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 StringIO
+import traceback
+
+from java.lang import IllegalStateException
+from java.io import IOException
+from javax.servlet import ServletException
+
+class ModjyException(Exception): pass
+
+class ModjyIOException(ModjyException): pass
+
+class ConfigException(ModjyException): pass
+class BadParameter(ConfigException): pass
+class ApplicationNotFound(ConfigException): pass
+class NoCallable(ConfigException): pass
+
+class RequestException(ModjyException): pass
+
+class ApplicationException(ModjyException): pass
+class StartResponseNotCalled(ApplicationException): pass
+class StartResponseCalledTwice(ApplicationException): pass
+class ResponseCommitted(ApplicationException): pass
+class HopByHopHeaderSet(ApplicationException): pass
+class WrongLength(ApplicationException): pass
+class BadArgument(ApplicationException): pass
+class ReturnNotIterable(ApplicationException): pass
+class NonStringOutput(ApplicationException): pass
+
+class exception_handler:
+
+ def handle(self, req, resp, environ, exc, exc_info):
+ pass
+
+ def get_status_and_message(self, req, resp, exc):
+ return resp.SC_INTERNAL_SERVER_ERROR, "Server configuration error"
+
+#
+# Special exception handler for testing
+#
+
+class testing_handler(exception_handler):
+
+ def handle(self, req, resp, environ, exc, exc_info):
+ typ, value, tb = exc_info
+ err_msg = StringIO.StringIO()
+ err_msg.write("%s: %s\n" % (typ, value,) )
+ err_msg.write(">Environment\n")
+ for k in environ.keys():
+ err_msg.write("%s=%s\n" % (k, repr(environ[k])) )
+ err_msg.write("<Environment\n")
+ err_msg.write(">TraceBack\n")
+ for line in traceback.format_exception(typ, value, tb):
+ err_msg.write(line)
+ err_msg.write("<TraceBack\n")
+ try:
+ status, message = self.get_status_and_message(req, resp, exc)
+ resp.setStatus(status)
+ resp.setContentLength(len(err_msg.getvalue()))
+ resp.getOutputStream().write(err_msg.getvalue())
+ except IllegalStateException, ise:
+ raise exc # Let the container deal with it
+
+#
+# Standard exception handler
+#
+
+class standard_handler(exception_handler):
+
+ def handle(self, req, resp, environ, exc, exc_info):
+ raise exc
Added: branches/modjy/Lib/modjy/modjy_impl.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_impl.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_impl.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,101 @@
+###
+#
+# Copyright 2004-2008 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 types
+import sys
+
+from modjy_exceptions import *
+
+class modjy_impl:
+
+ def deal_with_app_return(self, environ, start_response_callable, app_return):
+ self.log.debug("Processing app return type: %s" % str(type(app_return)))
+ if isinstance(app_return, types.StringTypes):
+ raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return)))
+ if type(app_return) is types.FileType:
+ pass # TBD: What to do here? can't call fileno()
+ if hasattr(app_return, '__len__') and callable(app_return.__len__):
+ expected_pieces = app_return.__len__()
+ else:
+ expected_pieces = -1
+ try:
+ try:
+ ix = 0
+ for next_piece in app_return:
+ if not isinstance(next_piece, types.StringType):
+ raise NonStringOutput("Application returned iterable containing non-strings: %s" % str(type(next_piece)))
+ if ix == 0:
+ # The application may have called start_response in the first iteration
+ if not start_response_callable.called:
+ raise StartResponseNotCalled("Start_response callable was never called.")
+ if not start_response_callable.content_length \
+ and expected_pieces == 1 \
+ and start_response_callable.write_callable.num_writes == 0:
+ # Take the length of the first piece
+ start_response_callable.set_content_length(len(next_piece))
+ start_response_callable.write_callable(next_piece)
+ ix += 1
+ if ix == expected_pieces:
+ break
+ if expected_pieces != -1 and ix != expected_pieces:
+ raise WrongLength("Iterator len() was wrong. Expected %d pieces: got %d" % (expected_pieces, ix) )
+ except AttributeError, ax:
+ if str(ax) == "__getitem__":
+ raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return)))
+ else:
+ raise ax
+ except TypeError, tx:
+ raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return)))
+ except ModjyException, mx:
+ raise mx
+ except Exception, x:
+ raise ApplicationException(x)
+ finally:
+ if hasattr(app_return, 'close') and callable(app_return.close):
+ app_return.close()
+
+ def init_impl(self):
+ self.do_j_env_params()
+
+ def add_packages(self, package_list):
+ packages = [p.strip() for p in package_list.split(';')]
+ for p in packages:
+ self.log.info("Adding java package %s to jython" % p)
+ sys.add_package(p)
+
+ def add_classdirs(self, classdir_list):
+ classdirs = [cd.strip() for cd in classdir_list.split(';')]
+ for cd in classdirs:
+ self.log.info("Adding directory %s to jython class file search path" % cd)
+ sys.add_classdir(cd)
+
+ def add_extdirs(self, extdir_list):
+ extdirs = [ed.strip() for ed in extdir_list.split(';')]
+ for ed in extdirs:
+ self.log.info("Adding directory %s for .jars and .zips search path" % ed)
+ sys.add_extdir(self.expand_relative_path(ed))
+
+ def do_j_env_params(self):
+ if self.params['packages']:
+ self.add_packages(self.params['packages'])
+ if self.params['classdirs']:
+ self.add_classdirs(self.params['classdirs'])
+ if self.params['extdirs']:
+ self.add_extdirs(self.params['extdirs'])
Added: branches/modjy/Lib/modjy/modjy_log.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_log.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_log.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,80 @@
+###
+#
+# Copyright 2004-2008 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 java
+
+import sys
+
+DEBUG = 'debug'
+INFO = 'info'
+WARN = 'warn'
+ERROR = 'error'
+FATAL = 'fatal'
+
+levels_dict = {}
+ix = 0
+for level in [DEBUG, INFO, WARN, ERROR, FATAL, ]:
+ levels_dict[level]=ix
+ ix += 1
+
+class modjy_logger:
+
+ def __init__(self, context):
+ self.log_ctx = context
+ self.format_str = "%(lvl)s:\t%(msg)s"
+ self.log_level = levels_dict[DEBUG]
+
+ def _log(self, level, level_str, msg, exc):
+ if level >= self.log_level:
+ msg = self.format_str % {'lvl': level_str, 'msg': msg, }
+ if exc:
+# java.lang.System.err.println(msg, exc)
+ self.log_ctx.log(msg, exc)
+ else:
+# java.lang.System.err.println(msg)
+ self.log_ctx.log(msg)
+
+ def debug(self, msg, exc=None):
+ self._log(0, DEBUG, msg, exc)
+
+ def info(self, msg, exc=None):
+ self._log(1, INFO, msg, exc)
+
+ def warn(self, msg, exc=None):
+ self._log(2, WARN, msg, exc)
+
+ def error(self, msg, exc=None):
+ self._log(3, ERROR, msg, exc)
+
+ def fatal(self, msg, exc=None):
+ self._log(4, FATAL, msg, exc)
+
+ def set_log_level(self, level_string):
+ try:
+ self.level = levels_dict[level_string]
+ except KeyError:
+ raise BadParameter("Invalid log level: '%s'" % level_string)
+
+ def set_log_format(self, format_string):
+ # BUG! Format string never actually used in this function.
+ try:
+ self._log(debug, "This is a log formatting test", None)
+ except KeyError:
+ raise BadParameter("Bad format string: '%s'" % format_string)
Added: branches/modjy/Lib/modjy/modjy_params.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_params.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_params.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,84 @@
+###
+#
+# Copyright 2004-2008 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
+#
+###
+
+from UserDict import UserDict
+
+BOOLEAN = ('boolean', int)
+INTEGER = ('integer', int)
+FLOAT = ('float', float)
+STRING = ('string', None)
+
+modjy_servlet_params = {
+
+ 'multithread': (BOOLEAN, 1),
+ 'cache_callables': (BOOLEAN, 1),
+ 'reload_on_mod': (BOOLEAN, 0),
+
+ 'app_import_name': (STRING, None),
+
+ 'app_directory': (STRING, None),
+ 'app_filename': (STRING, 'application.py'),
+ 'app_callable_name': (STRING, 'handler'),
+ 'callable_query_name': (STRING, None),
+
+ 'exc_handler': (STRING, 'standard'),
+
+ 'log_level': (STRING, 'info'),
+
+ 'packages': (STRING, None),
+ 'classdirs': (STRING, None),
+ 'extdirs': (STRING, None),
+
+ 'initial_env': (STRING, None),
+}
+
+class modjy_param_mgr(UserDict):
+
+ def __init__(self, param_types):
+ UserDict.__init__(self)
+ self.param_types = param_types
+ for pname in self.param_types.keys():
+ typ, default = self.param_types[pname]
+ self.__setitem__(pname, default)
+
+ def __getitem__(self, name):
+ return self._get_defaulted_value(name)
+
+ def __setitem__(self, name, value):
+ self.data[name] = self._convert_value(name, value)
+
+ def _convert_value(self, name, value):
+ if self.param_types.has_key(name):
+ typ, default = self.param_types[name]
+ typ_str, typ_func = typ
+ if typ_func:
+ try:
+ return typ_func(value)
+ except ValueError:
+ raise BadParameter("Illegal value for %s parameter '%s': %s" % (typ_str, name, value) )
+ return value
+
+ def _get_defaulted_value(self, name):
+ if self.data.has_key(name):
+ return self.data[name]
+ if self.param_types.has_key(name):
+ typ, default = self.param_types[name]
+ return default
+ raise KeyError(name)
Added: branches/modjy/Lib/modjy/modjy_publish.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_publish.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_publish.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,142 @@
+###
+#
+# Copyright 2004-2008 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):
+ script_name = "%s%s" % (req.getContextPath(), req.getServletPath())
+ path_info = req.getPathInfo() or ""
+ 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
+ environ["SCRIPT_NAME"] = script_name
+ environ["PATH_INFO"] = path_info
+ environ["PATH_TRANSLATED"] = File(self.app_directory, path_info).getPath()
+ return source_uri, callable_name
+
+ def get_app_object(self, req, environ):
+ 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:
+ 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
+ names = name.split('.') ; names.reverse()
+ imported = __import__(names.pop())
+ while names:
+ n = names.pop()
+ if n.endswith("()"):
+ n = n[:-2] ; instantiable = True
+ self.log.debug("importable '%s' is instantiable." % n)
+ if len(names) > 1:
+ names.reverse()
+ message = "Failed to import '%s': '%s' is not a valid method name" % (name, ".".join(names))
+ self.log.error(message)
+ self.raise_exc(ApplicationNotFound, message)
+ elif len(names) == 1:
+ method_name = names.pop()
+ else:
+ method_name = None
+ imported = getattr(imported, n)
+ self.log.debug("Imported '%s' from '%s'\n" % (n, str(imported)))
+ 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)) )
+
Added: branches/modjy/Lib/modjy/modjy_response.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_response.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_response.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,113 @@
+###
+#
+# Copyright 2004-2008 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 types
+
+from java.lang import System
+
+from modjy_exceptions import *
+from modjy_write import write_object
+
+# From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
+
+hop_by_hop_headers = {
+ 'connection': None,
+ 'keep-alive': None,
+ 'proxy-authenticate': None,
+ 'proxy-authorization': None,
+ 'te': None,
+ 'trailers': None,
+ 'transfer-encoding': None,
+ 'upgrade': None,
+}
+
+class start_response_object:
+
+ def __init__(self, req, resp):
+ self.http_req = req
+ self.http_resp = resp
+ self.write_callable = None
+ self.called = 0
+ self.content_length = None
+
+ # I'm doing the parameters this way to facilitate porting back to java
+ def __call__(self, *args, **keywords):
+ if len(args) < 2 or len(args) > 3:
+ raise BadArgument("Start response callback requires either two or three arguments: got %s" % str(args))
+ if len(args) == 3:
+ exc_info = args[2]
+ try:
+ try:
+ self.http_resp.reset()
+ except IllegalStateException, isx:
+ raise exc_info[0], exc_info[1], exc_info[2]
+ finally:
+ exc_info = None
+ else:
+ if self.called > 0:
+ raise StartResponseCalledTwice("Start response callback may only be called once, without exception information.")
+ status_str = args[0]
+ headers_list = args[1]
+ if not isinstance(status_str, types.StringType):
+ raise BadArgument("Start response callback requires string as first argument")
+ if not isinstance(headers_list, types.ListType):
+ raise BadArgument("Start response callback requires list as second argument")
+ try:
+ status_code, status_message_str = status_str.split(" ", 1)
+ self.http_resp.setStatus(int(status_code))
+ except ValueError:
+ raise BadArgument("Status string must be of the form '<int> <string>'")
+ self.make_write_object()
+ try:
+ for header_name, header_value in headers_list:
+ header_name_lower = header_name.lower()
+ if hop_by_hop_headers.has_key(header_name_lower):
+ raise HopByHopHeaderSet("Under WSGI, it is illegal to set hop-by-hop headers, i.e. '%s'" % header_name)
+ if header_name_lower == "content-length":
+ try:
+ self.set_content_length(int(header_value))
+ except ValueError, v:
+ raise BadArgument("Content-Length header value must be a string containing an integer, not '%s'" % header_value)
+ else:
+ final_value = header_value.encode('latin-1')
+ # Here would be the place to check for control characters, whitespace, etc
+ self.http_resp.addHeader(header_name, final_value)
+ except (AttributeError, TypeError), t:
+ raise BadArgument("Start response callback headers must contain a list of (<string>,<string>) tuples")
+ except UnicodeError, u:
+ raise BadArgument("Encoding error: header values may only contain latin-1 characters, not '%s'" % repr(header_value))
+ except ValueError, v:
+ raise BadArgument("Headers list must contain 2-tuples")
+ self.called += 1
+ return self.write_callable
+
+ def set_content_length(self, length):
+ if self.write_callable.num_writes == 0:
+ self.content_length = length
+ self.http_resp.setContentLength(length)
+ else:
+ raise ResponseCommitted("Cannot set content-length: response is already commited.")
+
+ def make_write_object(self):
+ try:
+ self.write_callable = write_object(self.http_resp.getOutputStream())
+ except IOException, iox:
+ raise IOError(iox)
+ return self.write_callable
Added: branches/modjy/Lib/modjy/modjy_write.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_write.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_write.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,43 @@
+###
+#
+# Copyright 2004-2008 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 types
+
+from modjy_exceptions import *
+
+class write_object:
+
+ def __init__(self, ostream):
+ self.ostream = ostream
+ self.num_writes = 0
+
+ def __call__(self, *args, **keywords):
+ if len(args) != 1 or type(args[0]) is not types.StringType:
+ raise NonStringOutput("Invocation of write callable requires exactly one string argument")
+ try:
+ self.ostream.write(args[0]) # Jython implicitly converts the (binary) string to a byte array
+ # WSGI requires that all output be flushed before returning to the application
+ # According to the java docs: " The flush method of OutputStream does nothing."
+ # Still, leave it in place for now: it's in the right place should this
+ # code ever be ported to another platform.
+ self.ostream.flush()
+ self.num_writes += 1
+ except Exception, x:
+ raise ModjyIOException(x)
Added: branches/modjy/Lib/modjy/modjy_wsgi.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_wsgi.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_wsgi.py 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,143 @@
+###
+#
+# Copyright 2004-2008 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
+#
+###
+
+from java.lang import System
+from org.python.core import PyFile
+
+from modjy_exceptions import *
+
+server_name = "modjy"
+server_param_prefix = "%s.param" % server_name
+j2ee_ns_prefix = "j2ee"
+
+class modjy_wsgi:
+
+ #
+ # WSGI constants
+ #
+
+ empty_pystring = ""
+ wsgi_version = (1,0)
+
+ #
+ # Container-specific constants
+ #
+
+ modjy_version = (0, 22, 3)
+
+ def set_string_envvar(self, dict, name, value, default_value):
+ if value == default_value:
+ dict[name] = self.empty_pystring
+ else:
+ dict[name] = value
+
+ def set_string_envvar_optional(self, dict, name, value, default_value):
+ if value != default_value:
+ dict[name] = str(value)
+
+ def set_int_envvar(self, dict, name, value, default_value):
+ if value == default_value:
+ dict[name] = self.empty_pystring
+ else:
+ dict[name] = str(value)
+
+ def set_container_specific_wsgi_vars(self, req, resp, dict, params):
+ dict["%s.version" % server_name] = self.modjy_version
+ for pname in params.keys():
+ dict["%s.%s" % (server_param_prefix, pname)] = params[pname]
+
+ def set_j2ee_specific_wsgi_vars(self, dict, j2ee_ns):
+ for p in j2ee_ns.keys():
+ dict["%s.%s" % (j2ee_ns_prefix, p)] = j2ee_ns[p]
+
+ def set_required_cgi_environ (self, req, resp, dict):
+ self.set_string_envvar(dict, "REQUEST_METHOD", req.getMethod(), None)
+ self.set_string_envvar(dict, "QUERY_STRING", req.getQueryString(), None)
+ self.set_string_envvar(dict, "CONTENT_TYPE", req.getContentType(), None)
+ self.set_int_envvar(dict, "CONTENT_LENGTH", req.getContentLength(), -1)
+ self.set_string_envvar(dict, "SERVER_NAME", req.getLocalName(), None)
+ self.set_int_envvar(dict, "SERVER_PORT", req.getLocalPort(), 0)
+
+ def set_other_cgi_environ (self, req, resp, dict):
+ if req.isSecure():
+ self.set_string_envvar(dict, "HTTPS", 'on', None)
+ else:
+ self.set_string_envvar(dict, "HTTPS", 'off', None)
+ self.set_string_envvar(dict, "SERVER_PROTOCOL", req.getProtocol(), None)
+ self.set_string_envvar(dict, "REMOTE_HOST", req.getRemoteHost(), None)
+ self.set_string_envvar(dict, "REMOTE_ADDR", req.getRemoteAddr(), None)
+ self.set_int_envvar(dict, "REMOTE_PORT", req.getRemotePort(), -1)
+ self.set_string_envvar_optional(dict, "AUTH_TYPE", req.getAuthType(), None)
+ self.set_string_envvar_optional(dict, "REMOTE_USER", req.getRemoteUser(), None)
+
+ def set_http_header_environ(self, req, resp, dict):
+ for curr_header_name in req.getHeaderNames():
+ values = None
+ for next_value in req.getHeaders(curr_header_name):
+ if values is None:
+ values = next_value
+ else:
+ if isinstance(values, types.ListType):
+ values.append(next_value)
+ else:
+ values = [values]
+ dict["HTTP_%s" % curr_header_name.replace('-', '_').upper()] = values
+
+ def set_required_wsgi_vars(self, req, resp, dict):
+ dict["wsgi.version"] = self.wsgi_version
+ dict["wsgi.url_scheme"] = req.getScheme()
+ dict["wsgi.multithread"] = \
+ int(dict["%s.cache_callables" % server_param_prefix]) \
+ and \
+ int(dict["%s.multithread" % server_param_prefix])
+ dict["wsgi.multiprocess"] = self.wsgi_multiprocess = 0
+ dict["wsgi.run_once"] = not(dict["%s.cache_callables" % server_param_prefix])
+
+ def set_wsgi_streams(self, req, resp, dict):
+ try:
+ dict["wsgi.input"] = PyFile(req.getInputStream())
+ dict["wsgi.errors"] = PyFile(System.err)
+ except IOException, iox:
+ raise ModjyIOException(iox)
+
+ def set_wsgi_classes(self, req, resp, dict):
+ # dict["wsgi.file_wrapper"] = modjy_file_wrapper
+ pass
+
+ def set_user_specified_environment(self, req, resp, wsgi_environ, params):
+ if not params.has_key('initial_env') or not params['initial_env']:
+ return
+ user_env_string = params['initial_env']
+ for l in user_env_string.split('\n'):
+ l = l.strip()
+ if l:
+ name, value = l.split(':', 1)
+ wsgi_environ[name.strip()] = value.strip()
+
+ def set_wsgi_environment(self, req, resp, wsgi_environ, params, j2ee_ns):
+ self.set_container_specific_wsgi_vars(req, resp, wsgi_environ, params)
+ self.set_j2ee_specific_wsgi_vars(wsgi_environ, j2ee_ns)
+ self.set_required_cgi_environ(req, resp, wsgi_environ)
+ self.set_other_cgi_environ(req, resp, wsgi_environ)
+ self.set_http_header_environ(req, resp, wsgi_environ)
+ self.set_required_wsgi_vars(req, resp, wsgi_environ)
+ self.set_wsgi_streams(req, resp, wsgi_environ)
+ self.set_wsgi_classes(req, resp, wsgi_environ)
+ self.set_user_specified_environment(req, resp, wsgi_environ, params)
Added: branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java
===================================================================
--- branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java (rev 0)
+++ branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java 2008-12-12 15:46:58 UTC (rev 5751)
@@ -0,0 +1,217 @@
+/*###
+#
+# Copyright 2004-2008 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://www.xhaus.com/modjy/LICENSE.txt
+#
+###*/
+
+package com.xhaus.modjy;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.python.core.*;
+import org.python.util.*;
+
+public class ModjyJServlet extends HttpServlet
+{
+
+ protected final static String MODJY_PYTHON_CLASSNAME = "modjy_servlet";
+ protected final static String LIB_PYTHON = "/WEB-INF/lib-python";
+ protected final static String PTH_FILE_EXTENSION = ".pth";
+
+ protected PythonInterpreter interp;
+ protected HttpServlet modjyServlet;
+
+ /**
+ * Read configuration
+ * 1. Both context and servlet parameters are included in the set,
+ * so that the definition of some parameters (e.g python.*) can be shared
+ * between multiple WSGI servlets.
+ * 2. servlet params take precedence over context parameters
+ */
+
+ protected Properties readConfiguration ( )
+ {
+ Properties props = new Properties();
+ // Context parameters
+ ServletContext context = getServletContext();
+ Enumeration e = context.getInitParameterNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String) e.nextElement();
+ props.put(name, context.getInitParameter(name));
+ }
+ // Servlet parameters override context parameters
+ e = getInitParameterNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String) e.nextElement();
+ props.put(name, getInitParameter(name));
+ }
+ return props;
+ }
+
+ /**
+ * Initialise the modjy servlet.
+ * 1. Read the configuration
+ * 2. Initialise the jython runtime
+ * 3. Setup, in relation to the J2EE servlet environment
+ * 4. Create the jython-implemented servlet
+ * 5. Initialise the jython-implemented servlet
+ */
+
+ public void init ( )
+ throws ServletException
+ {
+ try
+ {
+ Properties props = readConfiguration();
+ PythonInterpreter.initialize(System.getProperties(), props, new String[0]);
+ interp = new PythonInterpreter(null, new PySystemState());
+ String modjyJarLocation = setupEnvironment(props, Py.getSystemState());
+ try
+ { interp.exec("from modjy import "+MODJY_PYTHON_CLASSNAME); }
+ catch (PyException ix)
+ { throw new ServletException("Unable to import '"+MODJY_PYTHON_CLASSNAME+"' from "+modjyJarLocation+
+ ": do you maybe need to set the 'modjy_jar.location' parameter?");}
+ PyObject pyServlet = ((PyClass)interp.get(MODJY_PYTHON_CLASSNAME)).__call__();
+ Object temp = pyServlet.__tojava__(HttpServlet.class);
+ if (temp == Py.NoConversion)
+ throw new ServletException("Corrupted modjy file: cannot find definition of '"+MODJY_PYTHON_CLASSNAME+"' class");
+ modjyServlet = (HttpServlet) temp;
+ modjyServlet.init(this);
+ }
+ catch (PyException pyx)
+ {
+ throw new ServletException("Exception creating modjy servlet: " + pyx.toString(), pyx);
+ }
+ }
+
+ /**
+ * Actually service the incoming request.
+ * Simply delegate to the jython servlet.
+ *
+ * @param request - The incoming HttpServletRequest
+ * @param response - The outgoing HttpServletResponse
+ */
+
+ public void service ( HttpServletRequest req, HttpServletResponse resp )
+ throws ServletException, IOException
+ {
+ modjyServlet.service(req, resp);
+ }
+
+ /**
+ * Setup the modjy environment, i.e.
+ * 1. Find the location of the modjy.jar file and add it to sys.path
+ * 2. Process the WEB-INF/lib-python directory, if it exists
+ *
+ * @param props The properties from which config options are found
+ * @param systemState The PySystemState corresponding to the interpreter servicing requests
+ * @returns A String giving the path to the modjy.jar file (which is used only for error reporting)
+ */
+
+ protected String setupEnvironment(Properties props, PySystemState systemState)
+ {
+ String modjyJarLocation = locateModjyJar(props);
+ systemState.path.append(new PyString(modjyJarLocation));
+ processPythonLib(systemState);
+ return modjyJarLocation;
+ }
+
+ /**
+ * Find out the location of "modjy.jar", so that it can
+ * be added to the sys.path and thus imported
+ *
+ * @param The properties from which config options are found
+ * @returns A String giving the path to the modjy.jar file
+ */
+
+ protected String locateModjyJar ( Properties props )
+ {
+ // Give priority to modjy_jar.location
+ if (props.get("modjy_jar.location") != null)
+ return (String)props.get("modjy_jar.location");
+ // Then try to find it in WEB-INF/lib
+ String location = getServletContext().getRealPath("/WEB-INF/lib/modjy.jar");
+ if (location != null)
+ {
+ File f = new File(location);
+ if (f.exists())
+ return location;
+ }
+ // Try finding the archive that this class was loaded from
+ try
+ { return this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(); }
+ catch (Exception x)
+ { return null;}
+ }
+
+ /**
+ * Do all processing in relation to the lib-python subdirectory of WEB-INF
+ *
+ * @param systemState - The PySystemState whose path should be updated
+ */
+
+ protected void processPythonLib(PySystemState systemState)
+ {
+ // Add the lib-python directory to sys.path
+ String pythonLibPath = getServletContext().getRealPath(LIB_PYTHON);
+ if (pythonLibPath == null)
+ return;
+ File pythonLib = new File(pythonLibPath);
+ if (!pythonLib.exists())
+ return;
+ systemState.path.append(new PyString(pythonLibPath));
+ // Now check for .pth files in lib-python and process each one
+ String[] libPythonContents = pythonLib.list();
+ for (int ix = 0 ; ix < libPythonContents.length ; ix++)
+ if (libPythonContents[ix].endsWith(PTH_FILE_EXTENSION))
+ processPthFile(systemState, pythonLibPath, libPythonContents[ix]);
+ }
+
+ /**
+ * Process an individual file .pth file in the lib-python directory
+ *
+ * @param systemState - The PySystemState whose path should be updated
+ * @param pythonLibPath - The actual path to the lib-python directory
+ * @param pthFilename - The PySystemState whose path should be updated
+ */
+
+ protected void processPthFile(PySystemState systemState, String pythonLibPath, String pthFilename)
+ {
+ try
+ {
+ LineNumberReader lineReader = new LineNumberReader(new FileReader(new File(pythonLibPath, pthFilename)));
+ String line;
+ while ((line = lineReader.readLine()) != null)
+ {
+ line = line.trim();
+ if (line.startsWith("#"))
+ continue;
+ File archiveFile = new File(pythonLibPath, line);
+ String archiveRealpath = archiveFile.getAbsolutePath();
+ systemState.path.append(new PyString(archiveRealpath));
+ }
+ }
+ catch (IOException iox)
+ {
+ System.err.println("IOException: " + iox.toString());
+ }
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <am...@us...> - 2009-03-05 13:15:54
|
Revision: 6066
http://jython.svn.sourceforge.net/jython/?rev=6066&view=rev
Author: amak
Date: 2009-03-05 13:15:50 +0000 (Thu, 05 Mar 2009)
Log Message:
-----------
Removing old version of modjy, to get a fresh start on copying in the latest version.
Removed Paths:
-------------
branches/modjy/Lib/modjy/
branches/modjy/src/com/xhaus/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <am...@us...> - 2009-03-05 13:18:58
|
Revision: 6067
http://jython.svn.sourceforge.net/jython/?rev=6067&view=rev
Author: amak
Date: 2009-03-05 13:18:55 +0000 (Thu, 05 Mar 2009)
Log Message:
-----------
Copying over latest version of modjy, version 0.25.3.
Added Paths:
-----------
branches/modjy/Lib/modjy/
branches/modjy/Lib/modjy/__init__.py
branches/modjy/Lib/modjy/modjy.py
branches/modjy/Lib/modjy/modjy_exceptions.py
branches/modjy/Lib/modjy/modjy_impl.py
branches/modjy/Lib/modjy/modjy_log.py
branches/modjy/Lib/modjy/modjy_params.py
branches/modjy/Lib/modjy/modjy_publish.py
branches/modjy/Lib/modjy/modjy_response.py
branches/modjy/Lib/modjy/modjy_write.py
branches/modjy/Lib/modjy/modjy_wsgi.py
branches/modjy/src/com/xhaus/
branches/modjy/src/com/xhaus/modjy/
branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java
Added: branches/modjy/Lib/modjy/__init__.py
===================================================================
--- branches/modjy/Lib/modjy/__init__.py (rev 0)
+++ branches/modjy/Lib/modjy/__init__.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,22 @@
+###
+#
+# 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
+#
+###
+
+__all__ = ['modjy', 'modjy_exceptions', 'modjy_impl', 'modjy_log', 'modjy_params', 'modjy_publish', 'modjy_response', 'modjy_write', 'modjy_wsgi',]
+
Added: branches/modjy/Lib/modjy/modjy.py
===================================================================
--- branches/modjy/Lib/modjy/modjy.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,121 @@
+###
+#
+# 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 jarray
+import synchronize
+import sys
+import types
+
+sys.add_package("javax.servlet")
+sys.add_package("javax.servlet.http")
+sys.add_package("org.python.core")
+
+from modjy_exceptions import *
+from modjy_log import *
+from modjy_params import modjy_param_mgr, modjy_servlet_params
+from modjy_wsgi import modjy_wsgi
+from modjy_response import start_response_object
+from modjy_impl import modjy_impl
+from modjy_publish import modjy_publisher
+
+from javax.servlet.http import HttpServlet
+
+class modjy_servlet(HttpServlet, modjy_publisher, modjy_wsgi, modjy_impl):
+
+ def __init__(self):
+ HttpServlet.__init__(self)
+
+ def do_param(self, name, value):
+ if name[:3] == 'log':
+ getattr(self.log, "set_%s" % name)(value)
+ else:
+ self.params[name] = value
+
+ def process_param_container(self, param_container):
+ param_enum = param_container.getInitParameterNames()
+ while param_enum.hasMoreElements():
+ param_name = param_enum.nextElement()
+ self.do_param(param_name, param_container.getInitParameter(param_name))
+
+ def get_params(self):
+ self.process_param_container(self.servlet_context)
+ self.process_param_container(self.servlet)
+
+ def init(self, delegator):
+ self.servlet = delegator
+ self.servlet_context = self.servlet.getServletContext()
+ self.servlet_config = self.servlet.getServletConfig()
+ self.log = modjy_logger(self.servlet_context)
+ self.params = modjy_param_mgr(modjy_servlet_params)
+ self.get_params()
+ self.init_impl()
+ self.init_publisher()
+ import modjy_exceptions
+ self.exc_handler = getattr(modjy_exceptions, '%s_handler' % self.params['exc_handler'])()
+
+ def service (self, req, resp):
+ wsgi_environ = {}
+ try:
+ self.dispatch_to_application(req, resp, wsgi_environ)
+ except ModjyException, mx:
+ self.log.error("Exception servicing request: %s" % str(mx))
+ typ, value, tb = sys.exc_info()[:]
+ self.exc_handler.handle(req, resp, wsgi_environ, mx, (typ, value, tb) )
+
+ def get_j2ee_ns(self, req, resp):
+ return {
+ 'servlet': self.servlet,
+ 'servlet_context': self.servlet_context,
+ 'servlet_config': self.servlet_config,
+ 'request': req,
+ 'response': resp,
+ }
+
+ def dispatch_to_application(self, req, resp, environ):
+ app_callable = self.get_app_object(req, environ)
+ self.set_wsgi_environment(req, resp, environ, self.params, self.get_j2ee_ns(req, resp))
+ response_callable = start_response_object(req, resp)
+ try:
+ app_return = self.call_application(app_callable, environ, response_callable)
+ if app_return is None:
+ raise ReturnNotIterable("Application returned None: must return an iterable")
+ self.deal_with_app_return(environ, response_callable, app_return)
+ except ModjyException, mx:
+ self.raise_exc(mx.__class__, str(mx))
+ except Exception, x:
+ self.raise_exc(ApplicationException, str(x))
+
+ def call_application(self, app_callable, environ, response_callable):
+ if self.params['multithread']:
+ return app_callable.__call__(environ, response_callable)
+ else:
+ return synchronize.apply_synchronized( \
+ app_callable, \
+ app_callable, \
+ (environ, response_callable))
+
+ def expand_relative_path(self, path):
+ if path.startswith("$"):
+ return self.servlet.getServletContext().getRealPath(path[1:])
+ return path
+
+ def raise_exc(self, exc_class, message):
+ self.log.error(message)
+ raise exc_class(message)
Added: branches/modjy/Lib/modjy/modjy_exceptions.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_exceptions.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_exceptions.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,91 @@
+###
+#
+# 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 StringIO
+import traceback
+
+from java.lang import IllegalStateException
+from java.io import IOException
+from javax.servlet import ServletException
+
+class ModjyException(Exception): pass
+
+class ModjyIOException(ModjyException): pass
+
+class ConfigException(ModjyException): pass
+class BadParameter(ConfigException): pass
+class ApplicationNotFound(ConfigException): pass
+class NoCallable(ConfigException): pass
+
+class RequestException(ModjyException): pass
+
+class ApplicationException(ModjyException): pass
+class StartResponseNotCalled(ApplicationException): pass
+class StartResponseCalledTwice(ApplicationException): pass
+class ResponseCommitted(ApplicationException): pass
+class HopByHopHeaderSet(ApplicationException): pass
+class WrongLength(ApplicationException): pass
+class BadArgument(ApplicationException): pass
+class ReturnNotIterable(ApplicationException): pass
+class NonStringOutput(ApplicationException): pass
+
+class exception_handler:
+
+ def handle(self, req, resp, environ, exc, exc_info):
+ pass
+
+ def get_status_and_message(self, req, resp, exc):
+ return resp.SC_INTERNAL_SERVER_ERROR, "Server configuration error"
+
+#
+# Special exception handler for testing
+#
+
+class testing_handler(exception_handler):
+
+ def handle(self, req, resp, environ, exc, exc_info):
+ typ, value, tb = exc_info
+ err_msg = StringIO.StringIO()
+ err_msg.write("%s: %s\n" % (typ, value,) )
+ err_msg.write(">Environment\n")
+ for k in environ.keys():
+ err_msg.write("%s=%s\n" % (k, repr(environ[k])) )
+ err_msg.write("<Environment\n")
+ err_msg.write(">TraceBack\n")
+ for line in traceback.format_exception(typ, value, tb):
+ err_msg.write(line)
+ err_msg.write("<TraceBack\n")
+ try:
+ status, message = self.get_status_and_message(req, resp, exc)
+ resp.setStatus(status)
+ resp.setContentLength(len(err_msg.getvalue()))
+ resp.getOutputStream().write(err_msg.getvalue())
+ except IllegalStateException, ise:
+ raise exc # Let the container deal with it
+
+#
+# Standard exception handler
+#
+
+class standard_handler(exception_handler):
+
+ def handle(self, req, resp, environ, exc, exc_info):
+ raise exc_info[0], exc_info[1], exc_info[2]
Added: branches/modjy/Lib/modjy/modjy_impl.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_impl.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_impl.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,101 @@
+###
+#
+# 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 types
+import sys
+
+from modjy_exceptions import *
+
+class modjy_impl:
+
+ def deal_with_app_return(self, environ, start_response_callable, app_return):
+ self.log.debug("Processing app return type: %s" % str(type(app_return)))
+ if isinstance(app_return, types.StringTypes):
+ raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return)))
+ if type(app_return) is types.FileType:
+ pass # TBD: What to do here? can't call fileno()
+ if hasattr(app_return, '__len__') and callable(app_return.__len__):
+ expected_pieces = app_return.__len__()
+ else:
+ expected_pieces = -1
+ try:
+ try:
+ ix = 0
+ for next_piece in app_return:
+ if not isinstance(next_piece, types.StringTypes):
+ raise NonStringOutput("Application returned iterable containing non-strings: %s" % str(type(next_piece)))
+ if ix == 0:
+ # The application may have called start_response in the first iteration
+ if not start_response_callable.called:
+ raise StartResponseNotCalled("Start_response callable was never called.")
+ if not start_response_callable.content_length \
+ and expected_pieces == 1 \
+ and start_response_callable.write_callable.num_writes == 0:
+ # Take the length of the first piece
+ start_response_callable.set_content_length(len(next_piece))
+ start_response_callable.write_callable(next_piece)
+ ix += 1
+ if ix == expected_pieces:
+ break
+ if expected_pieces != -1 and ix != expected_pieces:
+ raise WrongLength("Iterator len() was wrong. Expected %d pieces: got %d" % (expected_pieces, ix) )
+ except AttributeError, ax:
+ if str(ax) == "__getitem__":
+ raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return)))
+ else:
+ raise ax
+ except TypeError, tx:
+ raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return)))
+ except ModjyException, mx:
+ raise mx
+ except Exception, x:
+ raise ApplicationException(x)
+ finally:
+ if hasattr(app_return, 'close') and callable(app_return.close):
+ app_return.close()
+
+ def init_impl(self):
+ self.do_j_env_params()
+
+ def add_packages(self, package_list):
+ packages = [p.strip() for p in package_list.split(';')]
+ for p in packages:
+ self.log.info("Adding java package %s to jython" % p)
+ sys.add_package(p)
+
+ def add_classdirs(self, classdir_list):
+ classdirs = [cd.strip() for cd in classdir_list.split(';')]
+ for cd in classdirs:
+ self.log.info("Adding directory %s to jython class file search path" % cd)
+ sys.add_classdir(cd)
+
+ def add_extdirs(self, extdir_list):
+ extdirs = [ed.strip() for ed in extdir_list.split(';')]
+ for ed in extdirs:
+ self.log.info("Adding directory %s for .jars and .zips search path" % ed)
+ sys.add_extdir(self.expand_relative_path(ed))
+
+ def do_j_env_params(self):
+ if self.params['packages']:
+ self.add_packages(self.params['packages'])
+ if self.params['classdirs']:
+ self.add_classdirs(self.params['classdirs'])
+ if self.params['extdirs']:
+ self.add_extdirs(self.params['extdirs'])
Added: branches/modjy/Lib/modjy/modjy_log.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_log.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_log.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,80 @@
+###
+#
+# 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 java
+
+import sys
+
+DEBUG = 'debug'
+INFO = 'info'
+WARN = 'warn'
+ERROR = 'error'
+FATAL = 'fatal'
+
+levels_dict = {}
+ix = 0
+for level in [DEBUG, INFO, WARN, ERROR, FATAL, ]:
+ levels_dict[level]=ix
+ ix += 1
+
+class modjy_logger:
+
+ def __init__(self, context):
+ self.log_ctx = context
+ self.format_str = "%(lvl)s:\t%(msg)s"
+ self.log_level = levels_dict[DEBUG]
+
+ def _log(self, level, level_str, msg, exc):
+ if level >= self.log_level:
+ msg = self.format_str % {'lvl': level_str, 'msg': msg, }
+ if exc:
+# java.lang.System.err.println(msg, exc)
+ self.log_ctx.log(msg, exc)
+ else:
+# java.lang.System.err.println(msg)
+ self.log_ctx.log(msg)
+
+ def debug(self, msg, exc=None):
+ self._log(0, DEBUG, msg, exc)
+
+ def info(self, msg, exc=None):
+ self._log(1, INFO, msg, exc)
+
+ def warn(self, msg, exc=None):
+ self._log(2, WARN, msg, exc)
+
+ def error(self, msg, exc=None):
+ self._log(3, ERROR, msg, exc)
+
+ def fatal(self, msg, exc=None):
+ self._log(4, FATAL, msg, exc)
+
+ def set_log_level(self, level_string):
+ try:
+ self.log_level = levels_dict[level_string]
+ except KeyError:
+ raise BadParameter("Invalid log level: '%s'" % level_string)
+
+ def set_log_format(self, format_string):
+ # BUG! Format string never actually used in this function.
+ try:
+ self._log(debug, "This is a log formatting test", None)
+ except KeyError:
+ raise BadParameter("Bad format string: '%s'" % format_string)
Added: branches/modjy/Lib/modjy/modjy_params.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_params.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_params.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,84 @@
+###
+#
+# 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
+#
+###
+
+from UserDict import UserDict
+
+BOOLEAN = ('boolean', int)
+INTEGER = ('integer', int)
+FLOAT = ('float', float)
+STRING = ('string', None)
+
+modjy_servlet_params = {
+
+ 'multithread': (BOOLEAN, 1),
+ 'cache_callables': (BOOLEAN, 1),
+ 'reload_on_mod': (BOOLEAN, 0),
+
+ 'app_import_name': (STRING, None),
+
+ 'app_directory': (STRING, None),
+ 'app_filename': (STRING, 'application.py'),
+ 'app_callable_name': (STRING, 'handler'),
+ 'callable_query_name': (STRING, None),
+
+ 'exc_handler': (STRING, 'standard'),
+
+ 'log_level': (STRING, 'info'),
+
+ 'packages': (STRING, None),
+ 'classdirs': (STRING, None),
+ 'extdirs': (STRING, None),
+
+ 'initial_env': (STRING, None),
+}
+
+class modjy_param_mgr(UserDict):
+
+ def __init__(self, param_types):
+ UserDict.__init__(self)
+ self.param_types = param_types
+ for pname in self.param_types.keys():
+ typ, default = self.param_types[pname]
+ self.__setitem__(pname, default)
+
+ def __getitem__(self, name):
+ return self._get_defaulted_value(name)
+
+ def __setitem__(self, name, value):
+ self.data[name] = self._convert_value(name, value)
+
+ def _convert_value(self, name, value):
+ if self.param_types.has_key(name):
+ typ, default = self.param_types[name]
+ typ_str, typ_func = typ
+ if typ_func:
+ try:
+ return typ_func(value)
+ except ValueError:
+ raise BadParameter("Illegal value for %s parameter '%s': %s" % (typ_str, name, value) )
+ return value
+
+ def _get_defaulted_value(self, name):
+ if self.data.has_key(name):
+ return self.data[name]
+ if self.param_types.has_key(name):
+ typ, default = self.param_types[name]
+ return default
+ raise KeyError(name)
Added: branches/modjy/Lib/modjy/modjy_publish.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_publish.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_publish.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,138 @@
+###
+#
+# 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)) )
+
Added: branches/modjy/Lib/modjy/modjy_response.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_response.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_response.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,113 @@
+###
+#
+# 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 types
+
+from java.lang import System
+
+from modjy_exceptions import *
+from modjy_write import write_object
+
+# From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
+
+hop_by_hop_headers = {
+ 'connection': None,
+ 'keep-alive': None,
+ 'proxy-authenticate': None,
+ 'proxy-authorization': None,
+ 'te': None,
+ 'trailers': None,
+ 'transfer-encoding': None,
+ 'upgrade': None,
+}
+
+class start_response_object:
+
+ def __init__(self, req, resp):
+ self.http_req = req
+ self.http_resp = resp
+ self.write_callable = None
+ self.called = 0
+ self.content_length = None
+
+ # I'm doing the parameters this way to facilitate porting back to java
+ def __call__(self, *args, **keywords):
+ if len(args) < 2 or len(args) > 3:
+ raise BadArgument("Start response callback requires either two or three arguments: got %s" % str(args))
+ if len(args) == 3:
+ exc_info = args[2]
+ try:
+ try:
+ self.http_resp.reset()
+ except IllegalStateException, isx:
+ raise exc_info[0], exc_info[1], exc_info[2]
+ finally:
+ exc_info = None
+ else:
+ if self.called > 0:
+ raise StartResponseCalledTwice("Start response callback may only be called once, without exception information.")
+ status_str = args[0]
+ headers_list = args[1]
+ if not isinstance(status_str, types.StringType):
+ raise BadArgument("Start response callback requires string as first argument")
+ if not isinstance(headers_list, types.ListType):
+ raise BadArgument("Start response callback requires list as second argument")
+ try:
+ status_code, status_message_str = status_str.split(" ", 1)
+ self.http_resp.setStatus(int(status_code))
+ except ValueError:
+ raise BadArgument("Status string must be of the form '<int> <string>'")
+ self.make_write_object()
+ try:
+ for header_name, header_value in headers_list:
+ header_name_lower = header_name.lower()
+ if hop_by_hop_headers.has_key(header_name_lower):
+ raise HopByHopHeaderSet("Under WSGI, it is illegal to set hop-by-hop headers, i.e. '%s'" % header_name)
+ if header_name_lower == "content-length":
+ try:
+ self.set_content_length(int(header_value))
+ except ValueError, v:
+ raise BadArgument("Content-Length header value must be a string containing an integer, not '%s'" % header_value)
+ else:
+ final_value = header_value.encode('latin-1')
+ # Here would be the place to check for control characters, whitespace, etc
+ self.http_resp.addHeader(header_name, final_value)
+ except (AttributeError, TypeError), t:
+ raise BadArgument("Start response callback headers must contain a list of (<string>,<string>) tuples")
+ except UnicodeError, u:
+ raise BadArgument("Encoding error: header values may only contain latin-1 characters, not '%s'" % repr(header_value))
+ except ValueError, v:
+ raise BadArgument("Headers list must contain 2-tuples")
+ self.called += 1
+ return self.write_callable
+
+ def set_content_length(self, length):
+ if self.write_callable.num_writes == 0:
+ self.content_length = length
+ self.http_resp.setContentLength(length)
+ else:
+ raise ResponseCommitted("Cannot set content-length: response is already commited.")
+
+ def make_write_object(self):
+ try:
+ self.write_callable = write_object(self.http_resp.getOutputStream())
+ except IOException, iox:
+ raise IOError(iox)
+ return self.write_callable
Added: branches/modjy/Lib/modjy/modjy_write.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_write.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_write.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,43 @@
+###
+#
+# 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 types
+
+from modjy_exceptions import *
+
+class write_object:
+
+ def __init__(self, ostream):
+ self.ostream = ostream
+ self.num_writes = 0
+
+ def __call__(self, *args, **keywords):
+ if len(args) != 1 or not isinstance(args[0], types.StringTypes):
+ raise NonStringOutput("Invocation of write callable requires exactly one string argument")
+ try:
+ self.ostream.write(args[0]) # Jython implicitly converts the (binary) string to a byte array
+ # WSGI requires that all output be flushed before returning to the application
+ # According to the java docs: " The flush method of OutputStream does nothing."
+ # Still, leave it in place for now: it's in the right place should this
+ # code ever be ported to another platform.
+ self.ostream.flush()
+ self.num_writes += 1
+ except Exception, x:
+ raise ModjyIOException(x)
Added: branches/modjy/Lib/modjy/modjy_wsgi.py
===================================================================
--- branches/modjy/Lib/modjy/modjy_wsgi.py (rev 0)
+++ branches/modjy/Lib/modjy/modjy_wsgi.py 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,156 @@
+###
+#
+# 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
+#
+###
+
+from java.lang import System
+
+try:
+ from org.python.core.util import FileUtil
+ create_py_file = FileUtil.wrap
+except ImportError:
+ from org.python.core import PyFile
+ create_py_file = PyFile
+
+from modjy_exceptions import *
+
+server_name = "modjy"
+server_param_prefix = "%s.param" % server_name
+j2ee_ns_prefix = "j2ee"
+
+cgi_var_char_encoding = "iso-8859-1"
+
+class modjy_wsgi:
+
+ #
+ # WSGI constants
+ #
+
+ empty_pystring = u""
+ wsgi_version = (1,0)
+
+ #
+ # Container-specific constants
+ #
+
+ modjy_version = (0, 25, 3)
+
+ def set_string_envvar(self, dict, name, value):
+ if value is None:
+ value = self.empty_pystring
+ value = value.encode(cgi_var_char_encoding)
+ dict[name] = value
+
+ def set_string_envvar_optional(self, dict, name, value, default_value):
+ if value != default_value:
+ self.set_string_envvar(dict, name, value)
+
+ def set_int_envvar(self, dict, name, value, default_value):
+ if value == default_value:
+ value = self.empty_pystring
+ else:
+ value = unicode(value)
+ self.set_string_envvar(dict, name, value)
+
+ def set_container_specific_wsgi_vars(self, req, resp, dict, params):
+ dict["%s.version" % server_name] = self.modjy_version
+ for pname in params.keys():
+ dict["%s.%s" % (server_param_prefix, pname)] = params[pname]
+
+ def set_j2ee_specific_wsgi_vars(self, dict, j2ee_ns):
+ for p in j2ee_ns.keys():
+ dict["%s.%s" % (j2ee_ns_prefix, p)] = j2ee_ns[p]
+
+ def set_required_cgi_environ (self, req, resp, dict):
+ self.set_string_envvar(dict, "REQUEST_METHOD", req.getMethod())
+ self.set_string_envvar(dict, "QUERY_STRING", req.getQueryString())
+ self.set_string_envvar(dict, "CONTENT_TYPE", req.getContentType())
+ self.set_int_envvar(dict, "CONTENT_LENGTH", req.getContentLength(), -1)
+ self.set_string_envvar(dict, "SERVER_NAME", req.getLocalName())
+ self.set_int_envvar(dict, "SERVER_PORT", req.getLocalPort(), 0)
+
+ def set_other_cgi_environ (self, req, resp, dict):
+ if req.isSecure():
+ self.set_string_envvar(dict, "HTTPS", 'on')
+ else:
+ self.set_string_envvar(dict, "HTTPS", 'off')
+ self.set_string_envvar(dict, "SERVER_PROTOCOL", req.getProtocol())
+ self.set_string_envvar(dict, "REMOTE_HOST", req.getRemoteHost())
+ self.set_string_envvar(dict, "REMOTE_ADDR", req.getRemoteAddr())
+ self.set_int_envvar(dict, "REMOTE_PORT", req.getRemotePort(), -1)
+ self.set_string_envvar_optional(dict, "AUTH_TYPE", req.getAuthType(), None)
+ self.set_string_envvar_optional(dict, "REMOTE_USER", req.getRemoteUser(), None)
+
+ def set_http_header_environ(self, req, resp, dict):
+ header_name_enum = req.getHeaderNames()
+ while header_name_enum.hasMoreElements():
+ curr_header_name = header_name_enum.nextElement()
+ values = None
+ values_enum = req.getHeaders(curr_header_name)
+ while values_enum.hasMoreElements():
+ next_value = values_enum.nextElement().encode(cgi_var_char_encoding)
+ if values is None:
+ values = next_value
+ else:
+ if isinstance(values, list):
+ values.append(next_value)
+ else:
+ values = [values]
+ dict["HTTP_%s" % str(curr_header_name).replace('-', '_').upper()] = values
+
+ def set_required_wsgi_vars(self, req, resp, dict):
+ dict["wsgi.version"] = self.wsgi_version
+ dict["wsgi.url_scheme"] = req.getScheme()
+ dict["wsgi.multithread"] = \
+ int(dict["%s.cache_callables" % server_param_prefix]) \
+ and \
+ int(dict["%s.multithread" % server_param_prefix])
+ dict["wsgi.multiprocess"] = self.wsgi_multiprocess = 0
+ dict["wsgi.run_once"] = not(dict["%s.cache_callables" % server_param_prefix])
+
+ def set_wsgi_streams(self, req, resp, dict):
+ try:
+ dict["wsgi.input"] = create_py_file(req.getInputStream())
+ dict["wsgi.errors"] = create_py_file(System.err)
+ except IOException, iox:
+ raise ModjyIOException(iox)
+
+ def set_wsgi_classes(self, req, resp, dict):
+ # dict["wsgi.file_wrapper"] = modjy_file_wrapper
+ pass
+
+ def set_user_specified_environment(self, req, resp, wsgi_environ, params):
+ if not params.has_key('initial_env') or not params['initial_env']:
+ return
+ user_env_string = params['initial_env']
+ for l in user_env_string.split('\n'):
+ l = l.strip()
+ if l:
+ name, value = l.split(':', 1)
+ wsgi_environ[name.strip()] = value.strip()
+
+ def set_wsgi_environment(self, req, resp, wsgi_environ, params, j2ee_ns):
+ self.set_container_specific_wsgi_vars(req, resp, wsgi_environ, params)
+ self.set_j2ee_specific_wsgi_vars(wsgi_environ, j2ee_ns)
+ self.set_required_cgi_environ(req, resp, wsgi_environ)
+ self.set_other_cgi_environ(req, resp, wsgi_environ)
+ self.set_http_header_environ(req, resp, wsgi_environ)
+ self.set_required_wsgi_vars(req, resp, wsgi_environ)
+ self.set_wsgi_streams(req, resp, wsgi_environ)
+ self.set_wsgi_classes(req, resp, wsgi_environ)
+ self.set_user_specified_environment(req, resp, wsgi_environ, params)
Added: branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java
===================================================================
--- branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java (rev 0)
+++ branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java 2009-03-05 13:18:55 UTC (rev 6067)
@@ -0,0 +1,224 @@
+/*###
+#
+# 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
+#
+###*/
+
+package com.xhaus.modjy;
+
+import java.io.*;
+import java.util.*;
+import javax.servlet.*;
+import javax.servlet.http.*;
+import org.python.core.*;
+import org.python.util.*;
+
+public class ModjyJServlet extends HttpServlet
+{
+
+ protected final static String MODJY_PYTHON_CLASSNAME = "modjy_servlet";
+ protected final static String LIB_PYTHON = "/WEB-INF/lib-python";
+ protected final static String PTH_FILE_EXTENSION = ".pth";
+
+ protected PythonInterpreter interp;
+ protected HttpServlet modjyServlet;
+
+ /**
+ * Read configuration
+ * 1. Both context and servlet parameters are included in the set,
+ * so that the definition of some parameters (e.g python.*) can be shared
+ * between multiple WSGI servlets.
+ * 2. servlet params take precedence over context parameters
+ */
+
+ protected Properties readConfiguration ( )
+ {
+ Properties props = new Properties();
+ // Context parameters
+ ServletContext context = getServletContext();
+ Enumeration e = context.getInitParameterNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String) e.nextElement();
+ props.put(name, context.getInitParameter(name));
+ }
+ // Servlet parameters override context parameters
+ e = getInitParameterNames();
+ while (e.hasMoreElements())
+ {
+ String name = (String) e.nextElement();
+ props.put(name, getInitParameter(name));
+ }
+ return props;
+ }
+
+ /**
+ * Initialise the modjy servlet.
+ * 1. Read the configuration
+ * 2. Initialise the jython runtime
+ * 3. Setup, in relation to the J2EE servlet environment
+ * 4. Create the jython-implemented servlet
+ * 5. Initialise the jython-implemented servlet
+ */
+
+ public void init ( )
+ throws ServletException
+ {
+ try
+ {
+ Properties props = readConfiguration();
+ PythonInterpreter.initialize(System.getProperties(), props, new String[0]);
+ PySystemState systemState = new PySystemState();
+ interp = new PythonInterpreter(null, systemState);
+ String modjyJarLocation = setupEnvironment(interp, props, systemState);
+ try
+ { interp.exec("from modjy import "+MODJY_PYTHON_CLASSNAME); }
+ catch (PyException ix)
+ { throw new ServletException("Unable to import '"+MODJY_PYTHON_CLASSNAME+"' from "+modjyJarLocation+
+ ": do you maybe need to set the 'modjy_jar.location' parameter?", ix);}
+ PyObject pyServlet = ((PyType)interp.get(MODJY_PYTHON_CLASSNAME)).__call__();
+ Object temp = pyServlet.__tojava__(HttpServlet.class);
+ if (temp == Py.NoConversion)
+ throw new ServletException("Corrupted modjy file: cannot find definition of '"+MODJY_PYTHON_CLASSNAME+"' class");
+ modjyServlet = (HttpServlet) temp;
+ modjyServlet.init(this);
+ }
+ catch (PyException pyx)
+ {
+ throw new ServletException("Exception creating modjy servlet: " + pyx.toString(), pyx);
+ }
+ }
+
+ /**
+ * Actually service the incoming request.
+ * Simply delegate to the jython servlet.
+ *
+ * @param request - The incoming HttpServletRequest
+ * @param response - The outgoing HttpServletResponse
+ */
+
+ public void service ( HttpServletRequest req, HttpServletResponse resp )
+ throws ServletException, IOException
+ {
+ modjyServlet.service(req, resp);
+ }
+
+ /**
+ * Setup the modjy environment, i.e.
+ * 1. Find the location of the modjy.jar file and add it to sys.path
+ * 2. Process the WEB-INF/lib-python directory, if it exists
+ *
+ * @param interp - The PythinInterpreter used to service requests
+ * @param props - The properties from which config options are found
+ * @param systemState - The PySystemState corresponding to the interpreter servicing requests
+ * @returns A String giving the path to the modjy.jar file (which is used only for error reporting)
+ */
+
+ protected String setupEnvironment(PythonInterpreter interp, Properties props, PySystemState systemState)
+ {
+ String modjyJarLocation = locateModjyJar(props);
+ systemState.path.append(new PyString(modjyJarLocation));
+ processPythonLib(interp, systemState);
+ return modjyJarLocation;
+ }
+
+ /**
+ * Find out the location of "modjy.jar", so that it can
+ * be added to the sys.path and thus imported
+ *
+ * @param The properties from which config options are found
+ * @returns A String giving the path to the modjy.jar file
+ */
+
+ protected String locateModjyJar ( Properties props )
+ {
+ // Give priority to modjy_jar.location
+ if (props.get("modjy_jar.location") != null)
+ return (String)props.get("modjy_jar.location");
+ // Then try to find it in WEB-INF/lib
+ String location = getServletContext().getRealPath("/WEB-INF/lib/modjy.jar");
+ if (location != null)
+ {
+ File f = new File(location);
+ if (f.exists())
+ return location;
+ }
+ // Try finding the archive that this class was loaded from
+ try
+ { return this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(); }
+ catch (Exception x)
+ { return null;}
+ }
+
+ /**
+ * Do all processing in relation to the lib-python subdirectory of WEB-INF
+ *
+ * @param interp - The PythinInterpreter used to service requests
+ * @param systemState - The PySystemState whose path should be updated
+ */
+
+ protected void processPythonLib(PythonInterpreter interp, PySystemState systemState)
+ {
+ // Add the lib-python directory to sys.path
+ String pythonLibPath = getServletContext().getRealPath(LIB_PYTHON);
+ if (pythonLibPath == null)
+ return;
+ File pythonLib = new File(pythonLibPath);
+ if (!pythonLib.exists())
+ return;
+ systemState.path.append(new PyString(pythonLibPath));
+ // Now check for .pth files in lib-python and process each one
+ String[] libPythonContents = pythonLib.list();
+ for (int ix = 0 ; ix < libPythonContents.length ; ix++)
+ if (libPythonContents[ix].endsWith(PTH_FILE_EXTENSION))
+ processPthFile(interp, systemState, pythonLibPath, libPythonContents[ix]);
+ }
+
+ /**
+ * Process an individual file .pth file in the lib-python directory
+ *
+ * @param systemState - The PySystemState whose path should be updated
+ * @param pythonLibPath - The actual path to the lib-python directory
+ * @param pthFilename - The PySystemState whose path should be updated
+ */
+
+ protected void processPthFile(PythonInterpreter interp, PySystemState systemState, String pythonLibPath, String pthFilename)
+ {
+ try
+ {
+ LineNumberReader lineReader = new LineNumberReader(new FileReader(new File(pythonLibPath, pthFilename)));
+ String line;
+ while ((line = lineReader.readLine()) != null)
+ {
+ line = line.trim();
+ if (line.length() == 0)
+ continue;
+ if (line.startsWith("#"))
+ continue;
+ if (line.startsWith("import"))
+ interp.exec(line);
+ File archiveFile = new File(pythonLibPath, line);
+ String archiveRealpath = archiveFile.getAbsolutePath();
+ systemState.path.append(new PyString(archiveRealpath));
+ }
+ }
+ catch (IOException iox)
+ {
+ System.err.println("IOException: " + iox.toString());
+ }
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <fwi...@us...> - 2009-03-06 16:42:05
|
Revision: 6073
http://jython.svn.sourceforge.net/jython/?rev=6073&view=rev
Author: fwierzbicki
Date: 2009-03-06 16:15:19 +0000 (Fri, 06 Mar 2009)
Log Message:
-----------
Merged revisions 5752,5756-5758,5761-5763,5765-5775,5778-5816,5818-5840,5842-5847,5854,5857-5859,5863-5865,5869,5875,5877,5884-5885,5889-5893,5900-5901,5903-5906,5908,5912-5918,5920,5923,5925,5927,5930-5932,5934-5947,5950-5951,5953-5957,5959,5961,5965-5966,5971-5976,5978-5979,5981-5983,5992,6001,6003,6006-6014,6023,6031-6037,6039-6040,6045-6047,6049-6052,6061-6065,6071 via svnmerge from
https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython
Modified Paths:
--------------
branches/modjy/.classpath
branches/modjy/CPythonLib.includes
branches/modjy/CoreExposed.includes
branches/modjy/LICENSE.txt
branches/modjy/Lib/decimal.py
branches/modjy/Lib/grp.py
branches/modjy/Lib/marshal.py
branches/modjy/Lib/new.py
branches/modjy/Lib/os.py
branches/modjy/Lib/platform.py
branches/modjy/Lib/pwd.py
branches/modjy/Lib/pydoc.py
branches/modjy/Lib/site.py
branches/modjy/Lib/socket.py
branches/modjy/Lib/test/regrtest.py
branches/modjy/Lib/test/string_tests.py
branches/modjy/Lib/test/test_StringIO_jy.py
branches/modjy/Lib/test/test_array.py
branches/modjy/Lib/test/test_array_jy.py
branches/modjy/Lib/test/test_builtin_jy.py
branches/modjy/Lib/test/test_class_jy.py
branches/modjy/Lib/test/test_cmd_line.py
branches/modjy/Lib/test/test_codeop.py
branches/modjy/Lib/test/test_descr_jy.py
branches/modjy/Lib/test/test_eof_jy.py
branches/modjy/Lib/test/test_func_syntax_jy.py
branches/modjy/Lib/test/test_genexps_jy.py
branches/modjy/Lib/test/test_grammar_jy.py
branches/modjy/Lib/test/test_import_jy.py
branches/modjy/Lib/test/test_java_integration.py
branches/modjy/Lib/test/test_java_visibility.py
branches/modjy/Lib/test/test_list_jy.py
branches/modjy/Lib/test/test_select.py
branches/modjy/Lib/test/test_socket.py
branches/modjy/Lib/test/test_support.py
branches/modjy/Lib/test/test_sys_jy.py
branches/modjy/Lib/test/test_thread_jy.py
branches/modjy/Lib/test/test_traceback.py
branches/modjy/Lib/test/test_tuple.py
branches/modjy/Lib/test/test_unicode_jy.py
branches/modjy/Lib/test/test_zlib.py
branches/modjy/Lib/threading.py
branches/modjy/Lib/zlib.py
branches/modjy/README.txt
branches/modjy/ast/Python.asdl
branches/modjy/ast/asdl_antlr.py
branches/modjy/ast/astview.py
branches/modjy/bugtests/README.txt
branches/modjy/bugtests/test386.py
branches/modjy/bugtests/test394.py
branches/modjy/bugtests/test394jar/MANIFEST.MF
branches/modjy/build.xml
branches/modjy/extlibs/jna-posix.jar
branches/modjy/grammar/Python.g
branches/modjy/grammar/PythonPartial.g
branches/modjy/registry
branches/modjy/src/com/ziclix/python/sql/handler/RowIdHandler.java
branches/modjy/src/org/python/antlr/GrammarActions.java
branches/modjy/src/org/python/antlr/PythonTokenSource.java
branches/modjy/src/org/python/antlr/adapter/AstAdapters.java
branches/modjy/src/org/python/antlr/ast/AssertDerived.java
branches/modjy/src/org/python/antlr/ast/AssignDerived.java
branches/modjy/src/org/python/antlr/ast/AttributeDerived.java
branches/modjy/src/org/python/antlr/ast/AugAssignDerived.java
branches/modjy/src/org/python/antlr/ast/BinOpDerived.java
branches/modjy/src/org/python/antlr/ast/BoolOpDerived.java
branches/modjy/src/org/python/antlr/ast/BreakDerived.java
branches/modjy/src/org/python/antlr/ast/CallDerived.java
branches/modjy/src/org/python/antlr/ast/ClassDefDerived.java
branches/modjy/src/org/python/antlr/ast/CompareDerived.java
branches/modjy/src/org/python/antlr/ast/ContinueDerived.java
branches/modjy/src/org/python/antlr/ast/DeleteDerived.java
branches/modjy/src/org/python/antlr/ast/DictDerived.java
branches/modjy/src/org/python/antlr/ast/EllipsisDerived.java
branches/modjy/src/org/python/antlr/ast/ExceptHandler.java
branches/modjy/src/org/python/antlr/ast/ExceptHandlerDerived.java
branches/modjy/src/org/python/antlr/ast/ExecDerived.java
branches/modjy/src/org/python/antlr/ast/ExprDerived.java
branches/modjy/src/org/python/antlr/ast/ExpressionDerived.java
branches/modjy/src/org/python/antlr/ast/ExtSliceDerived.java
branches/modjy/src/org/python/antlr/ast/ForDerived.java
branches/modjy/src/org/python/antlr/ast/FunctionDefDerived.java
branches/modjy/src/org/python/antlr/ast/GeneratorExpDerived.java
branches/modjy/src/org/python/antlr/ast/GlobalDerived.java
branches/modjy/src/org/python/antlr/ast/IfDerived.java
branches/modjy/src/org/python/antlr/ast/IfExpDerived.java
branches/modjy/src/org/python/antlr/ast/ImportDerived.java
branches/modjy/src/org/python/antlr/ast/ImportFromDerived.java
branches/modjy/src/org/python/antlr/ast/IndexDerived.java
branches/modjy/src/org/python/antlr/ast/InteractiveDerived.java
branches/modjy/src/org/python/antlr/ast/LambdaDerived.java
branches/modjy/src/org/python/antlr/ast/ListCompDerived.java
branches/modjy/src/org/python/antlr/ast/ListDerived.java
branches/modjy/src/org/python/antlr/ast/ModuleDerived.java
branches/modjy/src/org/python/antlr/ast/NameDerived.java
branches/modjy/src/org/python/antlr/ast/NumDerived.java
branches/modjy/src/org/python/antlr/ast/PassDerived.java
branches/modjy/src/org/python/antlr/ast/PrintDerived.java
branches/modjy/src/org/python/antlr/ast/Raise.java
branches/modjy/src/org/python/antlr/ast/RaiseDerived.java
branches/modjy/src/org/python/antlr/ast/ReprDerived.java
branches/modjy/src/org/python/antlr/ast/ReturnDerived.java
branches/modjy/src/org/python/antlr/ast/SliceDerived.java
branches/modjy/src/org/python/antlr/ast/StrDerived.java
branches/modjy/src/org/python/antlr/ast/SubscriptDerived.java
branches/modjy/src/org/python/antlr/ast/SuiteDerived.java
branches/modjy/src/org/python/antlr/ast/TryExceptDerived.java
branches/modjy/src/org/python/antlr/ast/TryFinallyDerived.java
branches/modjy/src/org/python/antlr/ast/TupleDerived.java
branches/modjy/src/org/python/antlr/ast/UnaryOpDerived.java
branches/modjy/src/org/python/antlr/ast/WhileDerived.java
branches/modjy/src/org/python/antlr/ast/WithDerived.java
branches/modjy/src/org/python/antlr/ast/YieldDerived.java
branches/modjy/src/org/python/antlr/ast/aliasDerived.java
branches/modjy/src/org/python/antlr/ast/argumentsDerived.java
branches/modjy/src/org/python/antlr/ast/comprehensionDerived.java
branches/modjy/src/org/python/antlr/ast/keywordDerived.java
branches/modjy/src/org/python/antlr/op/AddDerived.java
branches/modjy/src/org/python/antlr/op/AndDerived.java
branches/modjy/src/org/python/antlr/op/AugLoadDerived.java
branches/modjy/src/org/python/antlr/op/AugStoreDerived.java
branches/modjy/src/org/python/antlr/op/BitAndDerived.java
branches/modjy/src/org/python/antlr/op/BitOrDerived.java
branches/modjy/src/org/python/antlr/op/BitXorDerived.java
branches/modjy/src/org/python/antlr/op/DelDerived.java
branches/modjy/src/org/python/antlr/op/DivDerived.java
branches/modjy/src/org/python/antlr/op/EqDerived.java
branches/modjy/src/org/python/antlr/op/FloorDivDerived.java
branches/modjy/src/org/python/antlr/op/GtDerived.java
branches/modjy/src/org/python/antlr/op/GtEDerived.java
branches/modjy/src/org/python/antlr/op/InDerived.java
branches/modjy/src/org/python/antlr/op/InvertDerived.java
branches/modjy/src/org/python/antlr/op/IsDerived.java
branches/modjy/src/org/python/antlr/op/IsNotDerived.java
branches/modjy/src/org/python/antlr/op/LShiftDerived.java
branches/modjy/src/org/python/antlr/op/LoadDerived.java
branches/modjy/src/org/python/antlr/op/LtDerived.java
branches/modjy/src/org/python/antlr/op/LtEDerived.java
branches/modjy/src/org/python/antlr/op/ModDerived.java
branches/modjy/src/org/python/antlr/op/MultDerived.java
branches/modjy/src/org/python/antlr/op/NotDerived.java
branches/modjy/src/org/python/antlr/op/NotEqDerived.java
branches/modjy/src/org/python/antlr/op/NotInDerived.java
branches/modjy/src/org/python/antlr/op/OrDerived.java
branches/modjy/src/org/python/antlr/op/ParamDerived.java
branches/modjy/src/org/python/antlr/op/PowDerived.java
branches/modjy/src/org/python/antlr/op/RShiftDerived.java
branches/modjy/src/org/python/antlr/op/StoreDerived.java
branches/modjy/src/org/python/antlr/op/SubDerived.java
branches/modjy/src/org/python/antlr/op/UAddDerived.java
branches/modjy/src/org/python/antlr/op/USubDerived.java
branches/modjy/src/org/python/compiler/AdapterMaker.java
branches/modjy/src/org/python/compiler/ClassFile.java
branches/modjy/src/org/python/compiler/Code.java
branches/modjy/src/org/python/compiler/CodeCompiler.java
branches/modjy/src/org/python/compiler/Constant.java
branches/modjy/src/org/python/compiler/Future.java
branches/modjy/src/org/python/compiler/JavaMaker.java
branches/modjy/src/org/python/compiler/Module.java
branches/modjy/src/org/python/compiler/ProxyMaker.java
branches/modjy/src/org/python/compiler/ScopeInfo.java
branches/modjy/src/org/python/compiler/ScopesCompiler.java
branches/modjy/src/org/python/core/AbstractArray.java
branches/modjy/src/org/python/core/ArgParser.java
branches/modjy/src/org/python/core/AstList.java
branches/modjy/src/org/python/core/BaseSet.java
branches/modjy/src/org/python/core/BytecodeLoader.java
branches/modjy/src/org/python/core/CompilerFlags.java
branches/modjy/src/org/python/core/JavaImporter.java
branches/modjy/src/org/python/core/Options.java
branches/modjy/src/org/python/core/ParserFacade.java
branches/modjy/src/org/python/core/Py.java
branches/modjy/src/org/python/core/PyArray.java
branches/modjy/src/org/python/core/PyArrayDerived.java
branches/modjy/src/org/python/core/PyBaseExceptionDerived.java
branches/modjy/src/org/python/core/PyBoolean.java
branches/modjy/src/org/python/core/PyBooleanDerived.java
branches/modjy/src/org/python/core/PyBuiltinMethodNarrow.java
branches/modjy/src/org/python/core/PyClassMethod.java
branches/modjy/src/org/python/core/PyClassMethodDerived.java
branches/modjy/src/org/python/core/PyComplex.java
branches/modjy/src/org/python/core/PyComplexDerived.java
branches/modjy/src/org/python/core/PyDictionary.java
branches/modjy/src/org/python/core/PyDictionaryDerived.java
branches/modjy/src/org/python/core/PyEnumerate.java
branches/modjy/src/org/python/core/PyEnumerateDerived.java
branches/modjy/src/org/python/core/PyException.java
branches/modjy/src/org/python/core/PyFile.java
branches/modjy/src/org/python/core/PyFileDerived.java
branches/modjy/src/org/python/core/PyFloat.java
branches/modjy/src/org/python/core/PyFloatDerived.java
branches/modjy/src/org/python/core/PyFrame.java
branches/modjy/src/org/python/core/PyFrozenSet.java
branches/modjy/src/org/python/core/PyFrozenSetDerived.java
branches/modjy/src/org/python/core/PyFunction.java
branches/modjy/src/org/python/core/PyInstance.java
branches/modjy/src/org/python/core/PyInteger.java
branches/modjy/src/org/python/core/PyIntegerDerived.java
branches/modjy/src/org/python/core/PyIterator.java
branches/modjy/src/org/python/core/PyJavaPackage.java
branches/modjy/src/org/python/core/PyJavaType.java
branches/modjy/src/org/python/core/PyList.java
branches/modjy/src/org/python/core/PyListDerived.java
branches/modjy/src/org/python/core/PyLong.java
branches/modjy/src/org/python/core/PyLongDerived.java
branches/modjy/src/org/python/core/PyMethod.java
branches/modjy/src/org/python/core/PyMethodDescr.java
branches/modjy/src/org/python/core/PyModuleDerived.java
branches/modjy/src/org/python/core/PyNewWrapper.java
branches/modjy/src/org/python/core/PyObject.java
branches/modjy/src/org/python/core/PyObjectDerived.java
branches/modjy/src/org/python/core/PyObjectList.java
branches/modjy/src/org/python/core/PyProperty.java
branches/modjy/src/org/python/core/PyPropertyDerived.java
branches/modjy/src/org/python/core/PyReflectedConstructor.java
branches/modjy/src/org/python/core/PyReflectedFunction.java
branches/modjy/src/org/python/core/PySequence.java
branches/modjy/src/org/python/core/PySequenceList.java
branches/modjy/src/org/python/core/PySet.java
branches/modjy/src/org/python/core/PySetDerived.java
branches/modjy/src/org/python/core/PySlice.java
branches/modjy/src/org/python/core/PySliceDerived.java
branches/modjy/src/org/python/core/PyStaticMethod.java
branches/modjy/src/org/python/core/PyString.java
branches/modjy/src/org/python/core/PyStringDerived.java
branches/modjy/src/org/python/core/PyStringMap.java
branches/modjy/src/org/python/core/PySuper.java
branches/modjy/src/org/python/core/PySuperDerived.java
branches/modjy/src/org/python/core/PySystemState.java
branches/modjy/src/org/python/core/PyTableCode.java
branches/modjy/src/org/python/core/PyTraceback.java
branches/modjy/src/org/python/core/PyTuple.java
branches/modjy/src/org/python/core/PyTupleDerived.java
branches/modjy/src/org/python/core/PyType.java
branches/modjy/src/org/python/core/PyTypeDerived.java
branches/modjy/src/org/python/core/PyUnicode.java
branches/modjy/src/org/python/core/PyUnicodeDerived.java
branches/modjy/src/org/python/core/PyXRange.java
branches/modjy/src/org/python/core/ReflectedArgs.java
branches/modjy/src/org/python/core/SyspathJavaLoader.java
branches/modjy/src/org/python/core/ThreadStateMapping.java
branches/modjy/src/org/python/core/__builtin__.java
branches/modjy/src/org/python/core/adapter/ClassicPyObjectAdapter.java
branches/modjy/src/org/python/core/codecs.java
branches/modjy/src/org/python/core/exceptions.java
branches/modjy/src/org/python/core/imp.java
branches/modjy/src/org/python/core/io/FileIO.java
branches/modjy/src/org/python/core/io/IOBase.java
branches/modjy/src/org/python/core/io/ServerSocketIO.java
branches/modjy/src/org/python/core/packagecache/CachedJarsPackageManager.java
branches/modjy/src/org/python/core/packagecache/PackageManager.java
branches/modjy/src/org/python/core/packagecache/PathPackageManager.java
branches/modjy/src/org/python/expose/BaseTypeBuilder.java
branches/modjy/src/org/python/expose/generate/ClassMethodExposer.java
branches/modjy/src/org/python/expose/generate/DescriptorExposer.java
branches/modjy/src/org/python/expose/generate/ExposeTask.java
branches/modjy/src/org/python/expose/generate/ExposedFieldFinder.java
branches/modjy/src/org/python/expose/generate/ExposedMethodFinder.java
branches/modjy/src/org/python/expose/generate/ExposedTypeProcessor.java
branches/modjy/src/org/python/expose/generate/ExposedTypeVisitor.java
branches/modjy/src/org/python/expose/generate/Exposer.java
branches/modjy/src/org/python/expose/generate/InstanceMethodExposer.java
branches/modjy/src/org/python/expose/generate/MethodExposer.java
branches/modjy/src/org/python/expose/generate/NewExposer.java
branches/modjy/src/org/python/expose/generate/OverridableNewExposer.java
branches/modjy/src/org/python/expose/generate/PyTypes.java
branches/modjy/src/org/python/expose/generate/RestrictiveAnnotationVisitor.java
branches/modjy/src/org/python/expose/generate/TypeExposer.java
branches/modjy/src/org/python/modules/ArrayModule.java
branches/modjy/src/org/python/modules/Setup.java
branches/modjy/src/org/python/modules/_collections/PyDefaultDictDerived.java
branches/modjy/src/org/python/modules/_collections/PyDeque.java
branches/modjy/src/org/python/modules/_collections/PyDequeDerived.java
branches/modjy/src/org/python/modules/_csv/PyDialectDerived.java
branches/modjy/src/org/python/modules/_csv/PyWriter.java
branches/modjy/src/org/python/modules/_functools/PyPartialDerived.java
branches/modjy/src/org/python/modules/_newmodule.java
branches/modjy/src/org/python/modules/_py_compile.java
branches/modjy/src/org/python/modules/_weakref/GlobalRef.java
branches/modjy/src/org/python/modules/_weakref/ReferenceTypeDerived.java
branches/modjy/src/org/python/modules/_weakref/WeakrefModule.java
branches/modjy/src/org/python/modules/binascii.java
branches/modjy/src/org/python/modules/cPickle.java
branches/modjy/src/org/python/modules/cStringIO.java
branches/modjy/src/org/python/modules/errno.java
branches/modjy/src/org/python/modules/imp.java
branches/modjy/src/org/python/modules/random/PyRandomDerived.java
branches/modjy/src/org/python/modules/random/RandomModule.java
branches/modjy/src/org/python/modules/sre/PatternObject.java
branches/modjy/src/org/python/modules/struct.java
branches/modjy/src/org/python/modules/thread/PyLocal.java
branches/modjy/src/org/python/modules/thread/PyLocalDerived.java
branches/modjy/src/org/python/modules/time/Time.java
branches/modjy/src/org/python/modules/ucnhash.java
branches/modjy/src/org/python/modules/zipimport/zipimport.java
branches/modjy/src/org/python/modules/zipimport/zipimporter.java
branches/modjy/src/org/python/modules/zipimport/zipimporterDerived.java
branches/modjy/src/org/python/util/Generic.java
branches/modjy/src/org/python/util/InteractiveConsole.java
branches/modjy/src/org/python/util/JythoncAntTask.java
branches/modjy/src/org/python/util/NameUnionAntType.java
branches/modjy/src/org/python/util/jython.java
branches/modjy/src/shell/jython
branches/modjy/src/shell/jython.bat
branches/modjy/src/templates/gderived-defs
branches/modjy/src/templates/gderived.py
branches/modjy/src/templates/mappings
branches/modjy/src/templates/object.derived
branches/modjy/tests/java/javatests/ListTest.java
branches/modjy/tests/java/javatests/TestSupport.java
branches/modjy/tests/java/org/python/expose/generate/DescriptorExposerTest.java
branches/modjy/tests/java/org/python/expose/generate/ExposeMethodFinderTest.java
branches/modjy/tests/java/org/python/expose/generate/ExposedTypeProcessorTest.java
branches/modjy/tests/java/org/python/expose/generate/ExposedTypeVisitorTest.java
branches/modjy/tests/java/org/python/expose/generate/MethodExposerTest.java
branches/modjy/tests/java/org/python/expose/generate/NewExposerTest.java
branches/modjy/tests/java/org/python/expose/generate/OverridableNewExposerTest.java
branches/modjy/tests/java/org/python/expose/generate/TypeExposerTest.java
branches/modjy/tests/java/org/python/tests/Callbacker.java
branches/modjy/tests/java/org/python/tests/Invisible.java
branches/modjy/tests/java/org/python/tests/SubVisible.java
branches/modjy/tests/java/org/python/tests/VisibilityResults.java
branches/modjy/tests/java/org/python/tests/Visible.java
branches/modjy/tests/java/org/python/util/InterpreterTest.java
Added Paths:
-----------
branches/modjy/Lib/asyncore.py
branches/modjy/Lib/pycimport.py
branches/modjy/Lib/pyexpat.py
branches/modjy/Lib/signal.py
branches/modjy/Lib/test/access_protected_class.py
branches/modjy/Lib/test/access_protected_field.py
branches/modjy/Lib/test/anygui.py
branches/modjy/Lib/test/bug1239.jar
branches/modjy/Lib/test/call_protected_method.py
branches/modjy/Lib/test/check_for_initializer_in_syspath.py
branches/modjy/Lib/test/classimport.jar
branches/modjy/Lib/test/classimport_Lib.jar
branches/modjy/Lib/test/eof_fodder7.py
branches/modjy/Lib/test/except_in_raising_code.py
branches/modjy/Lib/test/import_nonexistent.py
branches/modjy/Lib/test/import_star_from_java.py
branches/modjy/Lib/test/invalid_utf_8_declared_encoding.py
branches/modjy/Lib/test/latin1_no_encoding.py
branches/modjy/Lib/test/output/test_signal
branches/modjy/Lib/test/python_home.policy
branches/modjy/Lib/test/sys_jy_test_module.py
branches/modjy/Lib/test/syspath_import.jar
branches/modjy/Lib/test/test_classpathimporter.py
branches/modjy/Lib/test/test_codeop_jy.py
branches/modjy/Lib/test/test_compile_jy.py
branches/modjy/Lib/test/test_doctest.py
branches/modjy/Lib/test/test_int_jy.py
branches/modjy/Lib/test/test_java_subclasses.py
branches/modjy/Lib/test/test_jython_initializer.py
branches/modjy/Lib/test/test_listcomp_jy.py
branches/modjy/Lib/test/test_marshal.py
branches/modjy/Lib/test/test_new.py
branches/modjy/Lib/test/test_pep263_jy.py
branches/modjy/Lib/test/test_sax_jy.py
branches/modjy/Lib/test/test_set_jy.py
branches/modjy/Lib/test/test_signal.py
branches/modjy/Lib/test/test_timeit.py
branches/modjy/Lib/test/test_traceback_jy.py
branches/modjy/Lib/test/test_xml_etree.py
branches/modjy/Lib/test/test_xml_etree_c.py
branches/modjy/Lib/test/test_xml_etree_jy.py
branches/modjy/Lib/test/test_zipimport_jy.py
branches/modjy/Lib/timeit.py
branches/modjy/Lib/xml/etree/
branches/modjy/Lib/xml/etree/cElementTree.py
branches/modjy/Lib/xml/parsers/
branches/modjy/Lib/xml/parsers/__init__.py
branches/modjy/Lib/xml/parsers/expat.py
branches/modjy/Misc/make_pydocs.py
branches/modjy/Tools/pbcvm/
branches/modjy/Tools/pbcvm/extract.py
branches/modjy/extlibs/antlr-3.1.2.jar
branches/modjy/extlibs/antlr-runtime-3.1.2.jar
branches/modjy/extlibs/cpptasks/
branches/modjy/extlibs/cpptasks/cpptasks.jar
branches/modjy/extlibs/modjy_0_25_3.zip
branches/modjy/extlibs/xercesImpl-2.9.1.jar
branches/modjy/src/org/python/compiler/MTime.java
branches/modjy/src/org/python/compiler/pbc/
branches/modjy/src/org/python/compiler/pbc/Bytecode.java
branches/modjy/src/org/python/compiler/pbc/BytecodeCompiler.java
branches/modjy/src/org/python/core/AnnotationReader.java
branches/modjy/src/org/python/core/BuiltinDocs.java
branches/modjy/src/org/python/core/ClasspathPyImporter.java
branches/modjy/src/org/python/core/ClasspathPyImporterDerived.java
branches/modjy/src/org/python/core/JythonInitializer.java
branches/modjy/src/org/python/core/Opcode.java
branches/modjy/src/org/python/core/PyBaseCode.java
branches/modjy/src/org/python/core/PyBytecode.java
branches/modjy/src/org/python/core/WrappedIterIterator.java
branches/modjy/src/org/python/core/util/importer.java
branches/modjy/src/org/python/modules/PyIOFile.java
branches/modjy/src/org/python/modules/PyIOFileFactory.java
branches/modjy/src/org/python/modules/_marshal.java
branches/modjy/src/org/python/util/GlobMatchingTask.java
branches/modjy/src/org/python/util/JycompileAntTask.java
branches/modjy/src/templates/ClasspathPyImporter.derived
branches/modjy/tests/data/
branches/modjy/tests/data/initializer/
branches/modjy/tests/data/initializer/META-INF/
branches/modjy/tests/data/initializer/META-INF/services/
branches/modjy/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer
branches/modjy/tests/data/initializer/SyspathAppendingInitializer.java
branches/modjy/tests/java/javatests/PySetInJavaTest.java
branches/modjy/tests/java/org/python/tests/BadStaticInitializer.java
branches/modjy/tests/java/org/python/tests/BeanImplementation.java
branches/modjy/tests/java/org/python/tests/BeanInterface.java
branches/modjy/tests/java/org/python/tests/Child.java
branches/modjy/tests/java/org/python/tests/Coercions.java
branches/modjy/tests/java/org/python/tests/CustomizableMapHolder.java
branches/modjy/tests/java/org/python/tests/ExceptionTest.java
branches/modjy/tests/java/org/python/tests/HiddenSuper.java
branches/modjy/tests/java/org/python/tests/Matryoshka.java
branches/modjy/tests/java/org/python/tests/OnlySubclassable.java
branches/modjy/tests/java/org/python/tests/OtherSubVisible.java
branches/modjy/tests/java/org/python/tests/Parent.java
branches/modjy/tests/java/org/python/tests/SomePyMethods.java
branches/modjy/tests/java/org/python/tests/inbred/
branches/modjy/tests/java/org/python/tests/inbred/Metis.java
branches/modjy/tests/java/org/python/tests/inbred/Zeus.java
branches/modjy/tests/java/org/python/tests/mro/
branches/modjy/tests/java/org/python/tests/mro/ConfusedOnGetitemAdd.java
branches/modjy/tests/java/org/python/tests/mro/ConfusedOnImport.java
branches/modjy/tests/java/org/python/tests/mro/FirstAndPost.java
branches/modjy/tests/java/org/python/tests/mro/FirstAndSecond.java
branches/modjy/tests/java/org/python/tests/mro/FirstPredefinedGetitem.java
branches/modjy/tests/java/org/python/tests/mro/GetitemAdder.java
branches/modjy/tests/java/org/python/tests/mro/PostAndFirst.java
branches/modjy/tests/java/org/python/tests/mro/PostdefinedGetitem.java
branches/modjy/tests/java/org/python/tests/mro/SecondAndFirst.java
branches/modjy/tests/java/org/python/tests/mro/SecondPredefinedGetitem.java
Removed Paths:
-------------
branches/modjy/Lib/asyncore.py
branches/modjy/Lib/test/test_bool.py
branches/modjy/Lib/test/test_exceptions.py
branches/modjy/Lib/test/test_jsubclass.py
branches/modjy/Lib/test/test_jy_compile.py
branches/modjy/Lib/xml/etree/cElementTree.py
branches/modjy/Lib/xml/parsers/__init__.py
branches/modjy/Lib/xml/parsers/expat.py
branches/modjy/Tools/pbcvm/extract.py
branches/modjy/bugtests/classes/test090j.java
branches/modjy/bugtests/classes/test092m/
branches/modjy/bugtests/classes/test119j.java
branches/modjy/bugtests/classes/test121p/
branches/modjy/bugtests/classes/test139j1.java
branches/modjy/bugtests/classes/test139j2.java
branches/modjy/bugtests/classes/test139j3.java
branches/modjy/bugtests/classes/test142j.java
branches/modjy/bugtests/classes/test160j1.java
branches/modjy/bugtests/classes/test160j2.java
branches/modjy/bugtests/classes/test182j.java
branches/modjy/bugtests/classes/test202j.java
branches/modjy/bugtests/classes/test204j0.java
branches/modjy/bugtests/classes/test204j1.java
branches/modjy/bugtests/classes/test204j2.java
branches/modjy/bugtests/classes/test204j3.java
branches/modjy/bugtests/classes/test205j0.java
branches/modjy/bugtests/classes/test205j1.java
branches/modjy/bugtests/classes/test205j2.java
branches/modjy/bugtests/classes/test206j0.java
branches/modjy/bugtests/classes/test206j1.java
branches/modjy/bugtests/classes/test208j.java
branches/modjy/bugtests/classes/test208j0.java
branches/modjy/bugtests/classes/test208j1.java
branches/modjy/bugtests/classes/test208j2.java
branches/modjy/bugtests/classes/test217p/
branches/modjy/bugtests/classes/test219e.java
branches/modjy/bugtests/classes/test219i.java
branches/modjy/bugtests/classes/test219j.java
branches/modjy/bugtests/classes/test220e.java
branches/modjy/bugtests/classes/test220i.java
branches/modjy/bugtests/classes/test220j.java
branches/modjy/bugtests/classes/test231j.java
branches/modjy/bugtests/classes/test231j2.java
branches/modjy/bugtests/classes/test232p/
branches/modjy/bugtests/classes/test236j1.java
branches/modjy/bugtests/classes/test236j2.java
branches/modjy/bugtests/classes/test246p/
branches/modjy/bugtests/classes/test248j.java
branches/modjy/bugtests/classes/test288i.java
branches/modjy/bugtests/classes/test288j.java
branches/modjy/bugtests/classes/test395j1.java
branches/modjy/bugtests/classes/test395j2.java
branches/modjy/bugtests/classes/test396j.java
branches/modjy/bugtests/test087.py
branches/modjy/bugtests/test087m.py
branches/modjy/bugtests/test088.py
branches/modjy/bugtests/test088p/
branches/modjy/bugtests/test090.py
branches/modjy/bugtests/test091.py
branches/modjy/bugtests/test091j.java
branches/modjy/bugtests/test092.py
branches/modjy/bugtests/test093.py
branches/modjy/bugtests/test094.py
branches/modjy/bugtests/test100.py
branches/modjy/bugtests/test100j.java
branches/modjy/bugtests/test101.py
branches/modjy/bugtests/test104.py
branches/modjy/bugtests/test114.py
branches/modjy/bugtests/test116.py
branches/modjy/bugtests/test117.py
branches/modjy/bugtests/test117j.java
branches/modjy/bugtests/test119.py
branches/modjy/bugtests/test120.py
branches/modjy/bugtests/test121.py
branches/modjy/bugtests/test122.py
branches/modjy/bugtests/test122p/
branches/modjy/bugtests/test123.py
branches/modjy/bugtests/test123j.java
branches/modjy/bugtests/test125m.py
branches/modjy/bugtests/test129.py
branches/modjy/bugtests/test129j.java
branches/modjy/bugtests/test132.py
branches/modjy/bugtests/test132j.java
branches/modjy/bugtests/test132m.py
branches/modjy/bugtests/test137.py
branches/modjy/bugtests/test137j.java
branches/modjy/bugtests/test145.py
branches/modjy/bugtests/test146.py
branches/modjy/bugtests/test147.py
branches/modjy/bugtests/test148.py
branches/modjy/bugtests/test149.py
branches/modjy/bugtests/test150.py
branches/modjy/bugtests/test151.py
branches/modjy/bugtests/test152.py
branches/modjy/bugtests/test153.py
branches/modjy/bugtests/test154.py
branches/modjy/bugtests/test154p/
branches/modjy/bugtests/test155.py
branches/modjy/bugtests/test156.py
branches/modjy/bugtests/test157.py
branches/modjy/bugtests/test157j.java
branches/modjy/bugtests/test158.py
branches/modjy/bugtests/test159.py
branches/modjy/bugtests/test160.py
branches/modjy/bugtests/test161.py
branches/modjy/bugtests/test162.py
branches/modjy/bugtests/test162m.py
branches/modjy/bugtests/test163.py
branches/modjy/bugtests/test164.py
branches/modjy/bugtests/test165.py
branches/modjy/bugtests/test166.py
branches/modjy/bugtests/test167.py
branches/modjy/bugtests/test168.py
branches/modjy/bugtests/test168p/
branches/modjy/bugtests/test169.py
branches/modjy/bugtests/test169c.py
branches/modjy/bugtests/test170.py
branches/modjy/bugtests/test170p/
branches/modjy/bugtests/test171.py
branches/modjy/bugtests/test171p/
branches/modjy/bugtests/test172.py
branches/modjy/bugtests/test172j.java
branches/modjy/bugtests/test173.py
branches/modjy/bugtests/test173p/
branches/modjy/bugtests/test174.py
branches/modjy/bugtests/test175.py
branches/modjy/bugtests/test176.py
branches/modjy/bugtests/test177.py
branches/modjy/bugtests/test178.py
branches/modjy/bugtests/test179.py
branches/modjy/bugtests/test180.py
branches/modjy/bugtests/test181.py
branches/modjy/bugtests/test182.py
branches/modjy/bugtests/test182c.py
branches/modjy/bugtests/test183.py
branches/modjy/bugtests/test184.py
branches/modjy/bugtests/test184s1.py
branches/modjy/bugtests/test184s2.py
branches/modjy/bugtests/test185.html
branches/modjy/bugtests/test185.py
branches/modjy/bugtests/test185a.py
branches/modjy/bugtests/test185m.py
branches/modjy/bugtests/test186.html
branches/modjy/bugtests/test186.py
branches/modjy/bugtests/test186a.py
branches/modjy/bugtests/test187.py
branches/modjy/bugtests/test187c.py
branches/modjy/bugtests/test188.py
branches/modjy/bugtests/test188c.py
branches/modjy/bugtests/test189.py
branches/modjy/bugtests/test189c.py
branches/modjy/bugtests/test190.py
branches/modjy/bugtests/test190c.py
branches/modjy/bugtests/test191.py
branches/modjy/bugtests/test191c.py
branches/modjy/bugtests/test192.html
branches/modjy/bugtests/test192.py
branches/modjy/bugtests/test192c.py
branches/modjy/bugtests/test192c1.py
branches/modjy/bugtests/test192c2.py
branches/modjy/bugtests/test193.py
branches/modjy/bugtests/test193c.py
branches/modjy/bugtests/test194.html
branches/modjy/bugtests/test194.py
branches/modjy/bugtests/test194c.py
branches/modjy/bugtests/test194m/
branches/modjy/bugtests/test195.py
branches/modjy/bugtests/test195c.py
branches/modjy/bugtests/test196.py
branches/modjy/bugtests/test196c.py
branches/modjy/bugtests/test197.py
branches/modjy/bugtests/test197c.py
branches/modjy/bugtests/test198.py
branches/modjy/bugtests/test198c.py
branches/modjy/bugtests/test199.py
branches/modjy/bugtests/test199c.py
branches/modjy/bugtests/test200.py
branches/modjy/bugtests/test200p1.py
branches/modjy/bugtests/test201.py
branches/modjy/bugtests/test201c.py
branches/modjy/bugtests/test202.py
branches/modjy/bugtests/test203.py
branches/modjy/bugtests/test204.py
branches/modjy/bugtests/test205.py
branches/modjy/bugtests/test206.py
branches/modjy/bugtests/test207.py
branches/modjy/bugtests/test208.py
branches/modjy/bugtests/test209.py
branches/modjy/bugtests/test209p/
branches/modjy/bugtests/test210.py
branches/modjy/bugtests/test211.py
branches/modjy/bugtests/test212.py
branches/modjy/bugtests/test213.py
branches/modjy/bugtests/test214.html
branches/modjy/bugtests/test214.py
branches/modjy/bugtests/test214a.py
branches/modjy/bugtests/test215.py
branches/modjy/bugtests/test216.py
branches/modjy/bugtests/test216s1.py
branches/modjy/bugtests/test217.py
branches/modjy/bugtests/test217c.py
branches/modjy/bugtests/test217t.java
branches/modjy/bugtests/test218.py
branches/modjy/bugtests/test218c.py
branches/modjy/bugtests/test219.py
branches/modjy/bugtests/test220.py
branches/modjy/bugtests/test220c.py
branches/modjy/bugtests/test221.py
branches/modjy/bugtests/test221c.py
branches/modjy/bugtests/test222.py
branches/modjy/bugtests/test222s.py
branches/modjy/bugtests/test223.py
branches/modjy/bugtests/test223s.py
branches/modjy/bugtests/test224.py
branches/modjy/bugtests/test224s.py
branches/modjy/bugtests/test225.py
branches/modjy/bugtests/test225s.py
branches/modjy/bugtests/test226.py
branches/modjy/bugtests/test226c.py
branches/modjy/bugtests/test227.py
branches/modjy/bugtests/test227c.py
branches/modjy/bugtests/test228.py
branches/modjy/bugtests/test228s.py
branches/modjy/bugtests/test229.py
branches/modjy/bugtests/test229c.py
branches/modjy/bugtests/test230.py
branches/modjy/bugtests/test231.py
branches/modjy/bugtests/test232.py
branches/modjy/bugtests/test233.py
branches/modjy/bugtests/test234.py
branches/modjy/bugtests/test235.py
branches/modjy/bugtests/test235p/
branches/modjy/bugtests/test237.py
branches/modjy/bugtests/test237m1.py
branches/modjy/bugtests/test237m2.py
branches/modjy/bugtests/test238.py
branches/modjy/bugtests/test239.py
branches/modjy/bugtests/test240.py
branches/modjy/bugtests/test242.py
branches/modjy/bugtests/test242c.py
branches/modjy/bugtests/test245.py
branches/modjy/bugtests/test245j.java
branches/modjy/bugtests/test246.py
branches/modjy/bugtests/test246c.py
branches/modjy/bugtests/test247.py
branches/modjy/bugtests/test247j.java
branches/modjy/bugtests/test248.py
branches/modjy/bugtests/test249.py
branches/modjy/bugtests/test249c.py
branches/modjy/bugtests/test250.py
branches/modjy/bugtests/test250j.java
branches/modjy/bugtests/test251.py
branches/modjy/bugtests/test251c.py
branches/modjy/bugtests/test251c2.py
branches/modjy/bugtests/test252.py
branches/modjy/bugtests/test252c.py
branches/modjy/bugtests/test252c2.py
branches/modjy/bugtests/test253.py
branches/modjy/bugtests/test253c.py
branches/modjy/bugtests/test253c2.py
branches/modjy/bugtests/test254.html
branches/modjy/bugtests/test254.py
branches/modjy/bugtests/test254c.py
branches/modjy/bugtests/test255.py
branches/modjy/bugtests/test255s1.py
branches/modjy/bugtests/test255s2.py
branches/modjy/bugtests/test256.html
branches/modjy/bugtests/test256.py
branches/modjy/bugtests/test256a.py
branches/modjy/bugtests/test257.py
branches/modjy/bugtests/test258.py
branches/modjy/bugtests/test258m1.py
branches/modjy/bugtests/test259.py
branches/modjy/bugtests/test259s.py
branches/modjy/bugtests/test260.py
branches/modjy/bugtests/test261.py
branches/modjy/bugtests/test261p/
branches/modjy/bugtests/test262.py
branches/modjy/bugtests/test262m.py
branches/modjy/bugtests/test262p/
branches/modjy/bugtests/test263.py
branches/modjy/bugtests/test263m.py
branches/modjy/bugtests/test264.py
branches/modjy/bugtests/test264c.py
branches/modjy/bugtests/test265.py
branches/modjy/bugtests/test265j.java
branches/modjy/bugtests/test266.py
branches/modjy/bugtests/test268.py
branches/modjy/bugtests/test268j1.java
branches/modjy/bugtests/test268j2.java
branches/modjy/bugtests/test269.py
branches/modjy/bugtests/test269p/
branches/modjy/bugtests/test270.py
branches/modjy/bugtests/test270p/
branches/modjy/bugtests/test271.py
branches/modjy/bugtests/test272.py
branches/modjy/bugtests/test272c.py
branches/modjy/bugtests/test273.py
branches/modjy/bugtests/test273p/
branches/modjy/bugtests/test274.py
branches/modjy/bugtests/test275.py
branches/modjy/bugtests/test275s.py
branches/modjy/bugtests/test276.py
branches/modjy/bugtests/test276j.java
branches/modjy/bugtests/test277.py
branches/modjy/bugtests/test277p/
branches/modjy/bugtests/test278.py
branches/modjy/bugtests/test278p/
branches/modjy/bugtests/test280.py
branches/modjy/bugtests/test280c.py
branches/modjy/bugtests/test281.py
branches/modjy/bugtests/test281c.py
branches/modjy/bugtests/test282.py
branches/modjy/bugtests/test284.py
branches/modjy/bugtests/test284j1.java
branches/modjy/bugtests/test284j2.java
branches/modjy/bugtests/test285.py
branches/modjy/bugtests/test286.py
branches/modjy/bugtests/test286c.py
branches/modjy/bugtests/test287.py
branches/modjy/bugtests/test288.py
branches/modjy/bugtests/test289.py
branches/modjy/bugtests/test289c.py
branches/modjy/bugtests/test290.py
branches/modjy/bugtests/test291.py
branches/modjy/bugtests/test292.policy
branches/modjy/bugtests/test292.py
branches/modjy/bugtests/test293.py
branches/modjy/bugtests/test293p/
branches/modjy/bugtests/test294.py
branches/modjy/bugtests/test294j.java
branches/modjy/bugtests/test295.py
branches/modjy/bugtests/test296.py
branches/modjy/bugtests/test296p/
branches/modjy/bugtests/test297.py
branches/modjy/bugtests/test297c.py
branches/modjy/bugtests/test298.py
branches/modjy/bugtests/test298m1.py
branches/modjy/bugtests/test299.py
branches/modjy/bugtests/test300.py
branches/modjy/bugtests/test301.py
branches/modjy/bugtests/test301c.py
branches/modjy/bugtests/test302.py
branches/modjy/bugtests/test303.py
branches/modjy/bugtests/test303j.java
branches/modjy/bugtests/test304.py
branches/modjy/bugtests/test304m.py
branches/modjy/bugtests/test307.py
branches/modjy/bugtests/test307foobar.template
branches/modjy/bugtests/test307m.template
branches/modjy/bugtests/test307p.template
branches/modjy/bugtests/test308.py
branches/modjy/bugtests/test308d/
branches/modjy/bugtests/test309.py
branches/modjy/bugtests/test310.py
branches/modjy/bugtests/test310c.py
branches/modjy/bugtests/test311.py
branches/modjy/bugtests/test312.py
branches/modjy/bugtests/test313.py
branches/modjy/bugtests/test313c.py
branches/modjy/bugtests/test314.py
branches/modjy/bugtests/test314c.py
branches/modjy/bugtests/test315.py
branches/modjy/bugtests/test315c.py
branches/modjy/bugtests/test316.py
branches/modjy/bugtests/test317.py
branches/modjy/bugtests/test317c.py
branches/modjy/bugtests/test318.py
branches/modjy/bugtests/test319.py
branches/modjy/bugtests/test319j.java
branches/modjy/bugtests/test320.py
branches/modjy/bugtests/test366.py
branches/modjy/bugtests/test373.py
branches/modjy/bugtests/test389.py
branches/modjy/bugtests/test391.py
branches/modjy/bugtests/test395.py
branches/modjy/bugtests/test396.py
branches/modjy/extlibs/antlr-3.1.1-runtime.jar
branches/modjy/extlibs/antlr-3.1.1.jar
branches/modjy/extlibs/cpptasks/cpptasks.jar
branches/modjy/extlibs/modjy_0_22_3.zip
branches/modjy/src/org/python/compiler/pbc/Bytecode.java
branches/modjy/src/org/python/compiler/pbc/BytecodeCompiler.java
branches/modjy/src/org/python/core/APIReader.java
branches/modjy/src/org/python/core/PySetIterator.java
branches/modjy/tests/data/initializer/
branches/modjy/tests/data/initializer/META-INF/
branches/modjy/tests/data/initializer/META-INF/services/
branches/modjy/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer
branches/modjy/tests/data/initializer/SyspathAppendingInitializer.java
branches/modjy/tests/java/javatests/MethodInvokationTest.java
branches/modjy/tests/java/org/python/tests/inbred/Metis.java
branches/modjy/tests/java/org/python/tests/inbred/Zeus.java
branches/modjy/tests/java/org/python/tests/mro/ConfusedOnGetitemAdd.java
branches/modjy/tests/java/org/python/tests/mro/ConfusedOnImport.java
branches/modjy/tests/java/org/python/tests/mro/FirstAndPost.java
branches/modjy/tests/java/org/python/tests/mro/FirstAndSecond.java
branches/modjy/tests/java/org/python/tests/mro/FirstPredefinedGetitem.java
branches/modjy/tests/java/org/python/tests/mro/GetitemAdder.java
branches/modjy/tests/java/org/python/tests/mro/PostAndFirst.java
branches/modjy/tests/java/org/python/tests/mro/PostdefinedGetitem.java
branches/modjy/tests/java/org/python/tests/mro/SecondAndFirst.java
branches/modjy/tests/java/org/python/tests/mro/SecondPredefinedGetitem.java
Property Changed:
----------------
branches/modjy/
Property changes on: branches/modjy
___________________________________________________________________
Modified: svn:externals
- CPythonLib http://svn.python.org/projects/python/branches/release25-maint/Lib/
+ CPythonLib -r70085 http://svn.python.org/projects/python/branches/release25-maint/Lib/
Modified: svnmerge-integrated
- /trunk/jython:1-5749
+ /trunk/jython:1-6072
Modified: branches/modjy/.classpath
===================================================================
--- branches/modjy/.classpath 2009-03-06 15:21:04 UTC (rev 6072)
+++ branches/modjy/.classpath 2009-03-06 16:15:19 UTC (rev 6073)
@@ -12,8 +12,10 @@
<classpathentry kind="lib" path="extlibs/mysql-connector-java-5.1.6.jar"/>
<classpathentry kind="lib" path="extlibs/postgresql-8.3-603.jdbc4.jar"/>
<classpathentry kind="lib" path="extlibs/servlet-api-2.5.jar"/>
- <classpathentry kind="lib" path="build/jarjar"/>
<classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/>
- <classpathentry kind="lib" path="extlibs/antlr-3.1.1-runtime.jar"/>
+ <classpathentry kind="lib" path="extlibs/antlr-runtime-3.1.2.jar"/>
+ <classpathentry kind="lib" path="extlibs/asm-3.1.jar"/>
+ <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/>
+ <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/>
<classpathentry kind="output" path="bugtests/classes"/>
</classpath>
Modified: branches/modjy/CPythonLib.includes
===================================================================
--- branches/modjy/CPythonLib.includes 2009-03-06 15:21:04 UTC (rev 6072)
+++ branches/modjy/CPythonLib.includes 2009-03-06 16:15:19 UTC (rev 6073)
@@ -8,6 +8,7 @@
encodings/**
logging/*
test/**
+xml/etree/**
# Lib files, in alphabetical order:
__future__.py
@@ -51,6 +52,8 @@
DocXMLRPCServer.py
dospath.py
dumbdbm.py
+dummy_thread.py
+dummy_threading.py
exceptions.py
fileinput.py
fnmatch.py
Modified: branches/modjy/CoreExposed.includes
===================================================================
--- branches/modjy/CoreExposed.includes 2009-03-06 15:21:04 UTC (rev 6072)
+++ branches/modjy/CoreExposed.includes 2009-03-06 16:15:19 UTC (rev 6073)
@@ -1,4 +1,5 @@
org/python/core/AstList.class
+org/python/core/ClasspathPyImporter.class
org/python/core/PyArray.class
org/python/core/PyBaseString.class
org/python/core/PyBaseException.class
@@ -33,6 +34,7 @@
org/python/core/PyStaticMethod.class
org/python/core/PyString.class
org/python/core/PySuper.class
+org/python/core/PyTraceback.class
org/python/core/PyTuple.class
org/python/core/PyType.class
org/python/core/PyUnicode.class
Modified: branches/modjy/LICENSE.txt
===================================================================
--- branches/modjy/LICENSE.txt 2009-03-06 15:21:04 UTC (rev 6072)
+++ branches/modjy/LICENSE.txt 2009-03-06 16:15:19 UTC (rev 6073)
@@ -53,7 +53,7 @@
Jython 2.0, 2.1 License
================================
-Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Jython Developers
+Copyright (c) 2000-2009 Jython Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
Deleted: branches/modjy/Lib/asyncore.py
===================================================================
--- branches/modjy/Lib/asyncore.py 2009-03-06 15:21:04 UTC (rev 6072)
+++ branches/modjy/Lib/asyncore.py 2009-03-06 16:15:19 UTC (rev 6073)
@@ -1,561 +0,0 @@
-# -*- Mode: Python -*-
-# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp
-# Author: Sam Rushing <ru...@ni...>
-
-# ======================================================================
-# Copyright 1996 by Sam Rushing
-#
-# All Rights Reserved
-#
-# Permission to use, copy, modify, and distribute this software and
-# its documentation for any purpose and without fee is hereby
-# granted, provided that the above copyright notice appear in all
-# copies and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of Sam
-# Rushing not be used in advertising or publicity pertaining to
-# distribution of the software without specific, written prior
-# permission.
-#
-# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-# ======================================================================
-
-"""Basic infrastructure for asynchronous socket service clients and servers.
-
-There are only two ways to have a program on a single processor do "more
-than one thing at a time". Multi-threaded programming is the simplest and
-most popular way to do it, but there is another very different technique,
-that lets you have nearly all the advantages of multi-threading, without
-actually using multiple threads. it's really only practical if your program
-is largely I/O bound. If your program is CPU bound, then pre-emptive
-scheduled threads are probably what you really need. Network servers are
-rarely CPU-bound, however.
-
-If your operating system supports the select() system call in its I/O
-library (and nearly all do), then you can use it to juggle multiple
-communication channels at once; doing other work while your I/O is taking
-place in the "background." Although this strategy can seem strange and
-complex, especially at first, it is in many ways easier to understand and
-control than multi-threaded programming. The module documented here solves
-many of the difficult problems for you, making the task of building
-sophisticated high-performance network servers and clients a snap.
-"""
-
-import exceptions
-import select
-import socket
-import sys
-import time
-
-import os
-from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \
- ENOTCONN, ESHUTDOWN, EINTR, EISCONN
-
-try:
- socket_map
-except NameError:
- socket_map = {}
-
-class ExitNow(exceptions.Exception):
- pass
-
-def read(obj):
- try:
- obj.handle_read_event()
- except ExitNow:
- raise
- except:
- obj.handle_error()
-
-def write(obj):
- try:
- obj.handle_write_event()
- except ExitNow:
- raise
- except:
- obj.handle_error()
-
-def readwrite(obj, flags):
- try:
- if flags & select.POLLIN:
- obj.handle_read_event()
- if flags & select.POLLOUT:
- obj.handle_write_event()
- except ExitNow:
- raise
- except:
- obj.handle_error()
-
-def poll(timeout=0.0, map=None):
- if map is None:
- map = socket_map
- if map:
- r = []; w = []; e = []
- for fd, obj in map.items():
- if obj.readable():
- r.append(fd)
- if obj.writable():
- w.append(fd)
- if [] == r == w == e:
- time.sleep(timeout)
- else:
- try:
- r, w, e = select.select(r, w, e, timeout)
- except select.error, err:
- if err[0] != EINTR:
- raise
- else:
- return
-
- for fd in r:
- obj = map.get(fd)
- if obj is None:
- continue
- read(obj)
-
- for fd in w:
- obj = map.get(fd)
- if obj is None:
- continue
- write(obj)
-
-def poll2(timeout=0.0, map=None):
- import poll
- if map is None:
- map = socket_map
- if timeout is not None:
- # timeout is in milliseconds
- timeout = int(timeout*1000)
- if map:
- l = []
- for fd, obj in map.items():
- flags = 0
- if obj.readable():
- flags = poll.POLLIN
- if obj.writable():
- flags = flags | poll.POLLOUT
- if flags:
- l.append((fd, flags))
- r = poll.poll(l, timeout)
- for fd, flags in r:
- obj = map.get(fd)
- if obj is None:
- continue
- readwrite(obj, flags)
-
-def poll3(timeout=0.0, map=None):
- # Use the poll() support added to the select module in Python 2.0
- if map is None:
- map = socket_map
- if timeout is not None:
- # timeout is in milliseconds
- timeout = int(timeout*1000)
- pollster = select.poll()
- if map:
- for fd, obj in map.items():
- flags = 0
- if obj.readable():
- flags = select.POLLIN
- if obj.writable():
- flags = flags | select.POLLOUT
- if flags:
- pollster.register(fd, flags)
- try:
- r = pollster.poll(timeout)
- except select.error, err:
- if err[0] != EINTR:
- raise
- r = []
- for fd, flags in r:
- obj = map.get(fd)
- if obj is None:
- continue
- readwrite(obj, flags)
-
-def loop(timeout=30.0, use_poll=0, map=None):
- if map is None:
- map = socket_map
-
- if use_poll:
- if hasattr(select, 'poll'):
- poll_fun = poll3
- else:
- poll_fun = poll2
- else:
- poll_fun = poll
-
- while map:
- poll_fun(timeout, map)
-
-class dispatcher:
-
- debug = 0
- connected = 0
- accepting = 0
- closing = 0
- addr = None
-
- def __init__(self, sock=None, map=None):
- if sock:
- self.set_socket(sock, map)
- # I think it should inherit this anyway
- self.socket.setblocking(0)
- self.connected = 1
- # XXX Does the constructor require that the socket passed
- # be connected?
- try:
- self.addr = sock.getpeername()
- except socket.error:
- # The addr isn't crucial
- pass
- else:
- self.socket = None
-
- def __repr__(self):
- status = [self.__class__.__module__+"."+self.__class__.__name__]
- if self.accepting and self.addr:
- status.append('listening')
- elif self.connected:
- status.append('connected')
- if self.addr is not None:
- try:
- status.append('%s:%d' % self.addr)
- except TypeError:
- status.append(repr(self.addr))
- # On some systems (RH10) id() can be a negative number.
- # work around this.
- MAX = 2L*sys.maxint+1
- return '<%s at %#x>' % (' '.join(status), id(self)&MAX)
-
- def add_channel(self, map=None):
- #self.log_info('adding channel %s' % self)
- if map is None:
- if hasattr(self, '_map'):
- map = self._map
- del self._map
- else:
- map = socket_map
- if not hasattr(self, '_fileno'):
- self._fileno = self.socket.fileno()
- map[self._fileno] = self
-
- def del_channel(self, map=None):
- fd = self._fileno
- if map is None:
- map = socket_map
- if map.has_key(fd):
- #self.log_info('closing channel %d:%s' % (fd, self))
- del map[fd]
-
- def create_socket(self, family, type):
- self.family_and_type = family, type
- self.socket = socket.socket(family, type)
- self.socket.setblocking(0)
-
- def set_socket(self, sock, map=None):
- self.socket = sock
-## self.__dict__['socket'] = sock
- if sock.fileno():
- self.add_channel(map)
- else:
- self._map = map
-
- def set_reuse_addr(self):
- # try to re-use a server port if possible
- try:
- self.socket.setsockopt(
- socket.SOL_SOCKET, socket.SO_REUSEADDR,
- self.socket.getsockopt(socket.SOL_SOCKET,
- socket.SO_REUSEADDR) | 1
- )
- except socket.error:
- pass
-
- # ==================================================
- # predicates for select()
- # these are used as filters for the lists of sockets
- # to pass to select().
- # ==================================================
-
- def readable(self):
- return True
-
- if os.name == 'mac':
- # The macintosh will select a listening socket for
- # write if you let it. What might this mean?
- def writable(self):
- return not self.accepting
- else:
- def writable(self):
- return True
-
- # ==================================================
- # socket object methods.
- # ==================================================
-
- def listen(self, num):
- self.accepting = 1
- if os.name == 'nt' and num > 5:
- num = 1
- ret = self.socket.listen(num)
- self.add_channel()
- return ret
-
- def bind(self, addr):
- self.addr = addr
- return self.socket.bind(addr)
-
- def connect(self, address):
- self.connected = 0
- err = self.socket.connect_ex(address)
- # XXX Should interpret Winsock return values
- if err in (EINPROGRESS, EALREADY, EWOULDBLOCK):
- return
- if err in (0, EISCONN):
- self.add_channel()
- self.addr = address
- self.connected = 1
- self.handle_connect()
- else:
- raise socket.error, err
-
- def accept(self):
- # XXX can return either an address pair or None
- try:
- conn, addr = self.socket.accept()
- self.add_channel()
- return conn, addr
- except socket.error, why:
- if why[0] == EWOULDBLOCK:
- pass
- else:
- raise socket.error, why
-
- def send(self, data):
- try:
- result = self.socket.send(data)
- return result
- except socket.error, why:
- if why[0] == EWOULDBLOCK:
- return 0
- else:
- raise socket.error, why
- return 0
-
- def recv(self, buffer_size):
- try:
- data = self.socket.recv(buffer_size)
- if not data:
- # a closed connection is indicated by signaling
- # a read condition, and having recv() return 0.
- self.handle_close()
- return ''
- else:
- return data
- except socket.error, why:
- # winsock sometimes throws ENOTCONN
- if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]:
- self.handle_close()
- return ''
- else:
- raise socket.error, why
-
- def close(self):
- self.del_channel()
- self.socket.close()
-
- # cheap inheritance, used to pass all other attribute
- # references to the underlying socket object.
- def __getattr__(self, attr):
- return getattr(self.socket, attr)
-
- # log and log_info may be overridden to provide more sophisticated
- # logging and warning methods. In general, log is for 'hit' logging
- # and 'log_info' is for informational, warning and error logging.
-
- def log(self, message):
- sys.stderr.write('log: %s\n' % str(message))
-
- def log_info(self, message, type='info'):
- if __debug__ or type != 'info':
- print '%s: %s' % (type, message)
-
- def handle_read_event(self):
- if self.accepting:
- # for an accepting socket, getting a read implies
- # that we are connected
- if not self.connected:
- self.connected = 1
- self.handle_accept()
- elif not self.connected:
- self.handle_connect()
- self.connected = 1
- self.handle_read()
- else:
- self.handle_read()
-
- def handle_write_event(self):
- # getting a write implies that we are connected
- if not self.connected:
- self.handle_connect()
- self.connected = 1
- self.handle_write()
-
- def handle_expt_event(self):
- self.handle_expt()
-
- def handle_error(self):
- nil, t, v, tbinfo = compact_traceback()
-
- # sometimes a user repr method will crash.
- try:
- self_repr = repr(self)
- except:
- self_repr = '<__repr__(self) failed for object at %0x>' % id(self)
-
- self.log_info(
- 'uncaptured python exception, closing channel %s (%s:%s %s)' % (
- self_repr,
- t,
- v,
- tbinfo
- ),
- 'error'
- )
- self.close()
-
- def handle_expt(self):
- self.log_info('unhandled exception', 'warning')
-
- def handle_read(self):
- self.log_info('unhandled read event', 'warning')
-
- def handle_write(self):
- self.log_info('unhandled write event', 'warning')
-
- def handle_connect(self):
- self.log_info('unhandled connect event', 'warning')
-
- def handle_accept(self):
- self.log_info('unhandled accept event', 'warning')
-
- def handle_close(self):
- self.log_info('unhandled close event', 'warning')
- self.close()
-
-# ---------------------------------------------------------------------------
-# adds simple buffered output capability, useful for simple clients.
-# [for more sophisticated usage use asynchat.async_chat]
-# ---------------------------------------------------------------------------
-
-class dispatcher_with_send(dispatcher):
-
- def __init__(self, sock=None):
- dispatcher.__init__(self, sock)
- self.out_buffer = ''
-
- def initiate_send(self):
- num_sent = 0
- num_sent = dispatcher.send(self, self.out_buffer[...
[truncated message content] |