changeset 136:7e160d2f6d9c

update HttpLib, untested git-svn-id: https://luan-java.googlecode.com/svn/trunk@137 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Wed, 11 Jun 2014 09:33:02 +0000
parents 3119326260ea
children 573ce091ae00
files src/luan/LuanElement.java src/luan/LuanState.java src/luan/lib/HttpLib.java src/luan/lib/IoLib.java src/luan/lib/PackageLib.java src/luan/tools/WebServlet.java src/luan/tools/cmd_line.luan
diffstat 7 files changed, 90 insertions(+), 108 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/LuanElement.java	Wed Jun 11 06:30:46 2014 +0000
+++ b/src/luan/LuanElement.java	Wed Jun 11 09:33:02 2014 +0000
@@ -4,7 +4,10 @@
 public abstract class LuanElement {
 
 	final String toString(String fnName) {
-		return location() + ": in " + (fnName==null ? "main chunk" : "function '"+fnName+"'");
+		String s = location();
+		if( fnName != null )
+			s += ": in function '" + fnName + "'";
+		return s;
 	}
 
 	abstract String location();
--- a/src/luan/LuanState.java	Wed Jun 11 06:30:46 2014 +0000
+++ b/src/luan/LuanState.java	Wed Jun 11 09:33:02 2014 +0000
@@ -17,6 +17,7 @@
 import luan.lib.BinaryLib;
 import luan.lib.IoLib;
 import luan.lib.ThreadLib;
+import luan.lib.HttpLib;
 
 
 public abstract class LuanState implements DeepCloneable<LuanState> {
@@ -152,6 +153,7 @@
 			luan.load(ThreadLib.NAME,ThreadLib.LOADER);
 			BasicLib.do_java_resource(luan,"luan/lib/init.luan");
 			luan.preload.put(JavaLib.NAME,JavaLib.LOADER);
+			luan.preload.put(HttpLib.NAME,HttpLib.LOADER);
 			return luan;
 		} catch(LuanException e) {
 			throw new RuntimeException(e);
--- a/src/luan/lib/HttpLib.java	Wed Jun 11 06:30:46 2014 +0000
+++ b/src/luan/lib/HttpLib.java	Wed Jun 11 09:33:02 2014 +0000
@@ -1,6 +1,6 @@
 package luan.lib;
 
-import java.io.PrintStream;
+import java.io.PrintWriter;
 import java.io.IOException;
 import java.util.Map;
 import java.util.Set;
@@ -17,50 +17,65 @@
 import luan.LuanTable;
 import luan.LuanJavaFunction;
 import luan.LuanExitException;
+import luan.DeepCloner;
 
 
 public final class HttpLib {
 
 	public static final String NAME = "Http";
-	public static final String FN_NAME = "Http.server";
+
+	public static final LuanFunction LOADER = new LuanFunction() {
+		@Override public Object call(LuanState luan,Object[] args) {
+			return new LuanTable();  // starts empty
+		}
+	};
 
-	public static void load(LuanState luan) throws LuanException {
-		PackageLib.require(luan,NAME);
-		Object fn = luan.get(HttpLib.FN_NAME);
-		if( !(fn instanceof LuanFunction) )
-			throw luan.exception( "function '"+HttpLib.FN_NAME+"' not defined" );
-	}
-
-	public static void service(LuanState luan,HttpServletRequest request,HttpServletResponse response)
-		throws LuanException, IOException
+	public static void service(LuanState luan,HttpServletRequest request,HttpServletResponse response,String modName)
+		throws LuanException
 	{
-		LuanFunction fn = (LuanFunction)luan.get(FN_NAME);
-		ServletOutputStream sout = response.getOutputStream();
-		luan.set( "Io.stdout", IoLib.textWriter(new PrintStream(sout)) );
+		LuanState newLuan;
+		LuanFunction newFn;
+		synchronized(luan) {
+			Object mod = PackageLib.require(luan,modName);
+			if( !(mod instanceof LuanFunction) )
+				throw luan.exception( "module '"+modName+"' must return a function" );
+			LuanFunction fn = (LuanFunction)mod;
+			DeepCloner cloner = new DeepCloner();
+			newLuan = cloner.deepClone(luan);
+			newFn = cloner.get(fn);
+		}
 
 		LuanTable module = (LuanTable)luan.loaded().get(NAME);
-
+		if( module == null )
+			throw luan.exception( "module 'Http' not defined" );
+		HttpLib lib = new HttpLib(request,response);
 		try {
-			new HttpLib(request,response,module);
+			module.put( "request", lib.requestTable() );
+			module.put( "response", lib.responseTable() );
+			module.put( "write", new LuanJavaFunction(
+				HttpLib.class.getMethod( "text_write", LuanState.class, new Object[0].getClass() ), lib
+			) );
 		} catch(NoSuchMethodException e) {
 			throw new RuntimeException(e);
 		}
 
-		luan.call(fn,FN_NAME);
+		newLuan.call(newFn,"<http>");
 	}
 
+
+
 	private final HttpServletRequest request;
 	private final HttpServletResponse response;
+	private PrintWriter writer = null;
+//	private ServletOutputStream sos = null;
 
-	private HttpLib(HttpServletRequest request,HttpServletResponse response,LuanTable module) throws NoSuchMethodException {
+	private HttpLib(HttpServletRequest request,HttpServletResponse response) {
 		this.request = request;
 		this.response = response;
+	}
 
+	private LuanTable requestTable() throws NoSuchMethodException {
 		LuanTable req = new LuanTable();
-		module.put("request",req);
-		LuanTable resp = new LuanTable();
-		module.put("response",resp);
-
 		req.put( "get_attribute", new LuanJavaFunction(HttpServletRequest.class.getMethod("getAttribute",String.class),request) );
 		req.put( "set_attribute", new LuanJavaFunction(HttpServletRequest.class.getMethod("setAttribute",String.class,Object.class),request) );
 		req.put( "get_parameter", new LuanJavaFunction(HttpServletRequest.class.getMethod("getParameter",String.class),request) );
@@ -72,19 +87,32 @@
 		req.put( "server_name", new LuanJavaFunction(HttpServletRequest.class.getMethod("getServerName"),request) );
 		add( req, "current_url" );
 		req.put( "remote_address", new LuanJavaFunction(HttpServletRequest.class.getMethod("getRemoteAddr"),request) );
+		return req;
+	}
 
+	private LuanTable responseTable() throws NoSuchMethodException {
+		LuanTable resp = new LuanTable();
 		add( resp, "send_redirect", String.class );
 		add( resp, "send_error", Integer.TYPE, String.class );
 		resp.put( "contains_header", new LuanJavaFunction(HttpServletResponse.class.getMethod("containsHeader",String.class),response) );
 		resp.put( "set_header", new LuanJavaFunction(HttpServletResponse.class.getMethod("setHeader",String.class,String.class),response) );
 		add( resp, "set_cookie", String.class, String.class, Boolean.TYPE, String.class );
 		add( resp, "remove_cookie", String.class, String.class );
+		return resp;
 	}
 
 	private void add(LuanTable t,String method,Class<?>... parameterTypes) throws NoSuchMethodException {
 		t.put( method, new LuanJavaFunction(HttpLib.class.getMethod(method,parameterTypes),this) );
 	}
 
+	public void text_write(LuanState luan,Object... args) throws LuanException, IOException {
+		if( writer == null )
+			writer = response.getWriter();
+		for( Object obj : args ) {
+			writer.print( luan.toString(obj) );
+		}
+	}
+
 	public String get_cookie_value(String name) {
 		return getCookieValue(request, name);
 	}
--- a/src/luan/lib/IoLib.java	Wed Jun 11 06:30:46 2014 +0000
+++ b/src/luan/lib/IoLib.java	Wed Jun 11 09:33:02 2014 +0000
@@ -93,7 +93,7 @@
 		return blocks(System.in,n);
 	}
 
-	public static String java_resource_to_url(String path) throws IOException {
+	public static String java_resource_to_url(String path) {
 		URL url = ClassLoader.getSystemResource(path);
 		return url==null ? null : url.toString();
 	}
@@ -425,4 +425,6 @@
 			}
 		};
 	}
+
+	private void IoLib() {}  // never
 }
--- a/src/luan/lib/PackageLib.java	Wed Jun 11 06:30:46 2014 +0000
+++ b/src/luan/lib/PackageLib.java	Wed Jun 11 09:33:02 2014 +0000
@@ -5,6 +5,7 @@
 import java.net.URL;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
 import luan.Luan;
 import luan.LuanState;
 import luan.LuanTable;
@@ -34,7 +35,7 @@
 			LuanTable searchers = luan.searchers();
 			searchers.add(preloadSearcher);
 			searchers.add(fileSearcher);
-			searchers.add(javaFileSearcher);
+			searchers.put("java",javaFileSearcher);
 			module.put("searchers",searchers);
 			return module;
 		}
@@ -48,12 +49,27 @@
 		LuanTable loaded = luan.loaded();
 		Object mod = loaded.get(modName);
 		if( mod == null ) {
+			List<Object> list = null;
+			String searchFor = modName;
 			LuanTable searchers = (LuanTable)luan.get("Package.searchers");
-			if( searchers == null )
-				searchers = new LuanTable(Collections.<Object>singletonList(preloadSearcher));
-			for( Object s : searchers.asList() ) {
+			if( searchers == null ) {
+				list = Collections.<Object>singletonList(preloadSearcher);
+			} else {
+				int i = modName.indexOf(':');
+				if( i != -1 ) {
+					String prefix = modName.substring(0,i);
+					Object searcher = searchers.get(prefix);
+					if( searcher != null ) {
+						list = Collections.<Object>singletonList(searcher);
+						searchFor = modName.substring(i+1);
+					}
+				}
+				if( list == null )
+					list = searchers.asList();
+			}
+			for( Object s : list ) {
 				LuanFunction searcher = (LuanFunction)s;
-				Object[] a = Luan.array(luan.call(searcher,"<searcher>",new Object[]{modName}));
+				Object[] a = Luan.array(luan.call(searcher,"<searcher>",new Object[]{searchFor}));
 				if( a.length >= 1 && a[0] instanceof LuanFunction ) {
 					LuanFunction loader = (LuanFunction)a[0];
 					a[0] = modName;
@@ -127,16 +143,10 @@
 
 	public static final LuanFunction javaFileSearcher = new LuanFunction() {
 		@Override public Object[] call(LuanState luan,Object[] args) {
-			String modName = (String)args[0];
-			String path = (String)luan.get("Package.jpath");
-			if( path==null )
-				return LuanFunction.NOTHING;
-			for( String s : path.split(";") ) {
-				String file = s.replaceAll("\\?",modName);
-				URL url = ClassLoader.getSystemResource(file);
-				if( url != null ) {
-					return new Object[]{javaFileLoader,url.toString()};
-				}
+			String path = (String)args[0];
+			String url = IoLib.java_resource_to_url(path);
+			if( url != null ) {
+				return new Object[]{javaFileLoader,url};
 			}
 			return LuanFunction.NOTHING;
 		}
--- a/src/luan/tools/WebServlet.java	Wed Jun 11 06:30:46 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-package luan.tools;
-
-import java.io.IOException;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import luan.LuanState;
-import luan.LuanException;
-import luan.LuanRuntimeException;
-import luan.LuanFunction;
-import luan.LuanElement;
-import luan.DeepCloner;
-import luan.interp.LuanCompiler;
-import luan.lib.HttpLib;
-import luan.lib.BasicLib;
-import luan.lib.PackageLib;
-import luan.lib.MathLib;
-import luan.lib.StringLib;
-import luan.lib.TableLib;
-import luan.lib.HtmlLib;
-
-
-public class WebServlet extends HttpServlet {
-
-	protected LuanState luanState = null;
-
-	protected LuanState newLuanState() throws LuanException {
-		LuanState luan = LuanCompiler.newLuanState();
-		luan.load(BasicLib.NAME,BasicLib.LOADER);
-		luan.load(PackageLib.NAME,PackageLib.LOADER);
-		luan.load(MathLib.NAME,MathLib.LOADER);
-		luan.load(StringLib.NAME,StringLib.LOADER);
-		luan.load(TableLib.NAME,TableLib.LOADER);
-		luan.load(HtmlLib.NAME,HtmlLib.LOADER);
-		return luan;
-	}
-
-	@Override protected void service(HttpServletRequest request,HttpServletResponse response)
-		throws ServletException, IOException
-	{
-		try {
-			synchronized(this) {
-				if( luanState == null ) {
-					luanState = newLuanState();
-					HttpLib.load(luanState);
-				}
-			}
-			LuanState luan = new DeepCloner().deepClone(luanState);
-			service(request,response,luan);
-		} catch(LuanException e) {
-			throw new LuanRuntimeException(e);
-		}
-	}
-
-	protected void service(HttpServletRequest request,HttpServletResponse response,LuanState luan)
-		throws ServletException, IOException, LuanException
-	{
-		HttpLib.service(luan,request,response);
-	}
-
-}
--- a/src/luan/tools/cmd_line.luan	Wed Jun 11 06:30:46 2014 +0000
+++ b/src/luan/tools/cmd_line.luan	Wed Jun 11 09:33:02 2014 +0000
@@ -38,15 +38,15 @@
 				return
 			end
 			local cmd = args[i]
-			local fn = load(cmd,"(command line)",true,true)
-			local result = Table.pack( fn() )
+			local stat = load(cmd,"(command line)",true,true)
+			local result = Table.pack( stat() )
 			if result.n > 0 then
 				print( Table.unpack(result,1,result.n) )
 			end
 		elseif arg == "-" then
 			local src = Io.stdin.read_text()
-			local fn = load(src,"stdin")
-			fn()
+			local stdin = load(src,"stdin")
+			stdin()
 			return
 		else
 			standalone_error( "unrecognized option '"..arg.."'" )
@@ -62,8 +62,8 @@
 	for j,v in ipairs(args) do
 		_G.arg[j-i] = v
 	end
-	local fn = load_file(file)
-	fn( Table.unpack(_G.arg) )
+	local main_file = load_file(file)
+	main_file( Table.unpack(_G.arg) )
 end
 if interactive then
 	Debug.debug("> ")