| ### |
| # |
| # 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']) |