Mercurial Hosting > luan
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("> ")