changeset 139:3b384dc5ca91

replace WebShell.java with web_shell.luan git-svn-id: https://luan-java.googlecode.com/svn/trunk@140 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 13 Jun 2014 12:26:44 +0000
parents 06159094b802
children f4ce03ff6b2f
files src/luan/interp/LuanParser.java src/luan/lib/BasicLib.java src/luan/lib/HttpLib.java src/luan/lib/init.luan src/luan/tools/WebShell.java src/luan/tools/web_run.luan src/luan/tools/web_shell.luan
diffstat 7 files changed, 140 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/interp/LuanParser.java	Thu Jun 12 08:20:48 2014 +0000
+++ b/src/luan/interp/LuanParser.java	Fri Jun 13 12:26:44 2014 +0000
@@ -423,7 +423,7 @@
 		parser.begin();
 		List<String> names = NameList(in);
 		if( names==null )
-			parser.exception("Name expected");
+			throw parser.exception("Name expected");
 		return parser.success(names);
 	}
 
@@ -433,13 +433,23 @@
 			return null;
 		List<String> names = new ArrayList<String>();
 		names.add(name);
-		while( parser.match( ',' ) ) {
-			Spaces(in);
-			names.add( RequiredName(in) );
+		while( (name=anotherName(in)) != null ) {
+			names.add(name);
 		}
 		return names;
 	}
 
+	private String anotherName(In in) throws ParseException {
+		parser.begin();
+		if( !parser.match( ',' ) )
+			return parser.failure(null);
+		Spaces(in);
+		String name = Name(in);
+		if( name==null )
+			return parser.failure(null);
+		return parser.success(name);
+	}
+
 	private Stmt WhileStmt() throws ParseException {
 		parser.begin();
 		if( !Keyword("while",In.NOTHING) )
@@ -1004,7 +1014,7 @@
 		parser.begin();
 		String name = Name(in);
 		if( name==null )
-			parser.exception("Name expected");
+			throw parser.exception("Name expected");
 		return parser.success(name);
 	}
 
--- a/src/luan/lib/BasicLib.java	Thu Jun 12 08:20:48 2014 +0000
+++ b/src/luan/lib/BasicLib.java	Fri Jun 13 12:26:44 2014 +0000
@@ -54,6 +54,7 @@
 				add( global, "to_string", LuanState.class, Object.class );
 				add( global, "type", Object.class );
 				global.put( "_VERSION", Luan.version );
+//				add( module, "new_luan" );
 				add( module, "values", new Object[0].getClass() );
 			} catch(NoSuchMethodException e) {
 				throw new RuntimeException(e);
@@ -241,5 +242,9 @@
 			}
 		};
 	}
-
+/*
+	public static LuanTable new_luan() {
+		return LuanState.newStandard().global();
+	}
+*/
 }
--- a/src/luan/lib/HttpLib.java	Thu Jun 12 08:20:48 2014 +0000
+++ b/src/luan/lib/HttpLib.java	Fri Jun 13 12:26:44 2014 +0000
@@ -10,6 +10,7 @@
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
 import luan.LuanState;
 import luan.LuanFunction;
 import luan.LuanElement;
@@ -30,20 +31,56 @@
 		}
 	};
 
-	public static void service(LuanState luan,HttpServletRequest request,HttpServletResponse response,String modName)
+	public static void service_per_request(LuanState luan,HttpServletRequest request,HttpServletResponse response,String modName)
 		throws LuanException
 	{
 		LuanFunction fn;
 		synchronized(luan) {
-			Object mod = PackageLib.require(luan,modName);
-			if( !(mod instanceof LuanFunction) )
-				throw luan.exception( "module '"+modName+"' must return a function" );
-			fn = (LuanFunction)mod;
+			fn = getFn(luan,modName);
 			DeepCloner cloner = new DeepCloner();
 			luan = cloner.deepClone(luan);
 			fn = cloner.get(fn);
 		}
+		service(luan,request,response,fn);
+	}
 
+	public static void service_global(LuanState luan,HttpServletRequest request,HttpServletResponse response,String modName)
+		throws LuanException
+	{
+		LuanFunction fn = getFn(luan,modName);
+		service(luan,request,response,fn);
+	}
+
+	public static void service_per_session(LuanState luan,HttpServletRequest request,HttpServletResponse response,String modName)
+		throws LuanException
+	{
+		HttpSession session = request.getSession();
+		LuanState sessionLuan  = (LuanState)session.getValue("luan");
+		if( sessionLuan!=null ) {
+			luan = sessionLuan;
+		} else {
+			DeepCloner cloner = new DeepCloner();
+			luan = cloner.deepClone(luan);
+			session.putValue("luan",luan);
+		}
+		LuanFunction fn = getFn(luan,modName);
+		service(luan,request,response,fn);
+	}
+
+	private static LuanFunction getFn(LuanState luan,String modName) throws LuanException {
+		Object mod = PackageLib.require(luan,modName);
+		if( !(mod instanceof LuanTable) )
+			throw luan.exception( "module '"+modName+"' must return a table" );
+		LuanTable tbl = (LuanTable)mod;
+		LuanFunction fn = (LuanFunction)tbl.get("page");
+		if( fn == null )
+			throw luan.exception( "function 'page' is not defined" );
+		return fn;
+	}
+
+	private static void service(LuanState luan,HttpServletRequest request,HttpServletResponse response,LuanFunction fn)
+		throws LuanException
+	{
 		LuanTable module = (LuanTable)luan.loaded().get(NAME);
 		if( module == null )
 			throw luan.exception( "module 'Http' not defined" );
@@ -88,6 +125,8 @@
 		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) );
+		add( req, "get_session_attribute", String.class );
+		add( req, "set_session_attribute", String.class, Object.class );
 		return req;
 	}
 
@@ -150,6 +189,14 @@
 		removeCookie(request,response,name,domain);
 	}
 
+	public Object get_session_attribute(String name) {
+		return request.getSession().getAttribute(name);
+	}
+
+	public void set_session_attribute(String name,Object value) {
+		request.getSession().setAttribute(name,value);
+	}
+
 
 	// static utils
 
--- a/src/luan/lib/init.luan	Thu Jun 12 08:20:48 2014 +0000
+++ b/src/luan/lib/init.luan	Fri Jun 13 12:26:44 2014 +0000
@@ -1,26 +1,33 @@
 --Io.stdout.write "this is init.luan\n"
 
-local function print(...)
+function Io.print_to(out,...)
 	local list = {}
 	for _,v in Basic.values(...) do
 		list[#list+1] = to_string(v)
 		list[#list+1] = '\t'
 	end
 	if #list == 0 then
-		Io.stdout.write( '\n' )
+		out.write( '\n' )
 	else
 		list[#list] = '\n'
-		Io.stdout.write( Table.unpack(list) )
+		out.write( Table.unpack(list) )
 	end
 end
 
-_G.print = print
-
+function _G.print(...)
+	Io.print_to(Io.stdout,...)
+end
 
 local Debug = {}
 Package.loaded.Debug = Debug
 _G.Debug = Debug
 
+function Debug.print_if_something(...)
+	if Table.pack(...).n > 0 then
+		_G.print(...)
+	end
+end
+
 function Debug.debug(prompt)
 	prompt = prompt or "luan_debug> "
 	local function console()
@@ -29,10 +36,7 @@
 	for line in console do
 		try
 			local fn = load(line,"stdin",true,true)
-			local result = Table.pack( fn() )
-			if result.n > 0 then
-				print( Table.unpack(result,1,result.n) )
-			end
+			Debug.print_if_something( fn() )
 		catch e do
 			print(e)
 		end
--- a/src/luan/tools/WebShell.java	Thu Jun 12 08:20:48 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-package luan.tools;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.Writer;
-import java.io.PrintWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.OutputStreamWriter;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import luan.Luan;
-import luan.LuanFunction;
-import luan.LuanState;
-import luan.LuanTable;
-import luan.LuanException;
-import luan.lib.BasicLib;
-import luan.lib.HtmlLib;
-import luan.lib.IoLib;
-
-
-public class WebShell extends HttpServlet {
-	private static final Logger logger = LoggerFactory.getLogger(WebShell.class);
-
-	protected LuanState newLuanState() throws LuanException {
-		return LuanState.newStandard();
-	}
-
-	protected Object[] eval(LuanState luan,String cmd) throws LuanException {
-		return Luan.array(luan.eval(cmd));
-	}
-
-	@Override protected void service(HttpServletRequest request,HttpServletResponse response)
-		throws ServletException, IOException
-	{
-		PrintWriter out = response.getWriter();
-		HttpSession session = request.getSession();
-
-		ByteArrayOutputStream history = (ByteArrayOutputStream)session.getValue("luan_history");
-		if( history==null ) {
-			history = new ByteArrayOutputStream();
-			session.putValue("luan_history",history);
-		}
-
-		if( request.getParameter("clear") != null ) {
-			history.reset();
-		} else {
-			String cmd = request.getParameter("cmd");
-			if( cmd != null ) {
-				Writer writer = new OutputStreamWriter(history);
-				writer.write( "% " + HtmlLib.encode(cmd) + "\r\n" );
-				writer.flush();
-				try {
-					LuanState luan  = (LuanState)session.getValue("luan");
-					if( luan==null ) {
-						luan = newLuanState();
-						session.putValue("luan",luan);
-					}
-					luan.set( "Io.stdout", IoLib.textWriter(new PrintStream(history)) );
-					LuanTable env = luan.global();
-					env.put("request",request);
-					env.put("response",response);
-					Object[] result = eval(luan,cmd);
-					if( result.length > 0 ) {
-						for( int i=0; i<result.length; i++ ) {
-							if( i > 0 )
-								writer.write("  ");
-							writer.write(HtmlLib.encode(luan.toString(result[i])));
-						}
-						writer.write("\r\n");
-					}
-				} catch(LuanException e) {
-					logger.info("",e);
-					writer.write( HtmlLib.encode(e.toString()) );
-					writer.write("\r\n");
-				}
-				writer.flush();
-			}
-		}
-
-		out.println( "<html>" );
-		out.println( "<title>Luan Shell</title>" );
-		out.println( "<body>" );
-		out.println( "<p>This is a command shell.  Enter commands below." );
-		out.println( "<pre>" + history + "</pre>" );
-		out.println( "<form name='theForm' method='post'>" );
-		out.println( "% <input name='cmd' size=60>" );
-		out.println( "<input type=submit value=run>" );
-		out.println( "<input type=submit name=clear value=clear>" );
-		out.println( "</form>" );
-		
-		out.println( "<script>document.theForm.cmd.focus();</script>" );
-		
-		out.println( "<p>" );
-		out.println( "</body>" );
-		out.println( "</html>" );
-	}
-}
--- a/src/luan/tools/web_run.luan	Thu Jun 12 08:20:48 2014 +0000
+++ b/src/luan/tools/web_run.luan	Fri Jun 13 12:26:44 2014 +0000
@@ -16,7 +16,7 @@
 	end
 end
 
-return function()
+function page()
 	Http.response.set_content_type "text/plain"
 	Io.stdout = Http.response.text_writer()
 	local code = Http.request.get_parameter "code"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/tools/web_shell.luan	Fri Jun 13 12:26:44 2014 +0000
@@ -0,0 +1,53 @@
+import "Http"
+
+local history = {}
+
+Io.stdout = {}
+function Io.stdout.write(...)
+	for _,v in Basic.values(...) do
+		history[#history+1] = v
+	end
+end
+
+function page()
+	if Http.request.get_parameter("clear") ~= nil then
+		history = {}
+	else
+		local cmd = Http.request.get_parameter("cmd")
+		if cmd ~= nil then
+			print( "% "..cmd )
+			try
+				local line = load(cmd,"<web_shell>",true,true);
+				Debug.print_if_something( line() )
+			catch e do
+				Io.print_to(Io.stderr,e)
+				print(e)
+			end
+		end
+	end
+
+	local write = Http.response.text_writer().write
+	write %>
+<html>
+<title>Luan Shell</title>
+	<body>
+		<p>This is a command shell.  Enter commands below.
+		<pre><%
+		for _,v in ipairs(history) do
+			write(v)
+		end
+		write %></pre>
+		<form name='theForm' method='post'>
+			% <input name='cmd' size=60>
+			<input type=submit value=run>
+			<input type=submit name=clear value=clear>
+		</form>
+		
+		<script>document.theForm.cmd.focus();</script>
+		
+		<p/>
+	</body>
+</html>
+<%
+
+end