changeset 226:392105b660d7

add LuanProperty git-svn-id: https://luan-java.googlecode.com/svn/trunk@227 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Tue, 22 Jul 2014 06:23:13 +0000
parents 7c768f63bbb3
children c0f87c1ba99f
files core/src/luan/Luan.java core/src/luan/LuanProperty.java core/src/luan/LuanPropertyTable.java core/src/luan/LuanTableImpl.java web/src/luan/modules/web/HttpLuan.java web/src/luan/modules/web/web_run.luan
diffstat 6 files changed, 123 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
diff -r 7c768f63bbb3 -r 392105b660d7 core/src/luan/Luan.java
--- a/core/src/luan/Luan.java	Tue Jul 22 03:06:27 2014 +0000
+++ b/core/src/luan/Luan.java	Tue Jul 22 06:23:13 2014 +0000
@@ -149,5 +149,9 @@
 		return new LuanTableImpl();
 	}
 
+	public static LuanTable newPropertyTable() {
+		return new LuanPropertyTable();
+	}
+
 	private Luan() {}  // never
 }
diff -r 7c768f63bbb3 -r 392105b660d7 core/src/luan/LuanProperty.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/src/luan/LuanProperty.java	Tue Jul 22 06:23:13 2014 +0000
@@ -0,0 +1,13 @@
+package luan;
+
+
+public abstract class LuanProperty {
+
+	public abstract Object get();
+
+	// return whether handled.  if not handled, then this object will be replaced
+	public boolean set(Object value) {
+		return false;
+	}
+
+}
diff -r 7c768f63bbb3 -r 392105b660d7 core/src/luan/LuanPropertyTable.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/src/luan/LuanPropertyTable.java	Tue Jul 22 06:23:13 2014 +0000
@@ -0,0 +1,58 @@
+package luan;
+
+import java.util.Set;
+import java.util.Map;
+import java.util.AbstractMap;
+import java.util.Iterator;
+
+
+class LuanPropertyTable extends LuanTableImpl {
+
+	@Override public LuanTableImpl shallowClone() {
+		return new LuanPropertyTable();
+	}
+
+	private Object fixValue(Object obj) {
+		return obj instanceof LuanProperty ? ((LuanProperty)obj).get() : obj;
+	}
+
+	@Override String repr(Set<LuanTableImpl> set,Object obj) {
+		return super.repr(set,fixValue(obj));
+	}
+
+	@Override public Object get(Object key) {
+		return fixValue(super.get(key));
+	}
+
+	@Override public void put(Object key,Object val) {
+		Object v = super.get(key);
+		if( v instanceof LuanProperty ) {
+			LuanProperty lp = (LuanProperty)v;
+			if( lp.set(val) )
+				return;
+		}
+		super.put(key,val);
+	}
+
+	@Override public Iterator<Map.Entry<Object,Object>> iterator() {
+		final Iterator<Map.Entry<Object,Object>> i = super.iterator();
+		return new Iterator<Map.Entry<Object,Object>>() {
+			public boolean hasNext() {
+				return i.hasNext();
+			}
+			public Map.Entry<Object,Object> next() {
+				Map.Entry<Object,Object> entry = i.next();
+				Object v = entry.getValue();
+				if( v instanceof LuanProperty ) {
+					LuanProperty lp = (LuanProperty)v;
+					return new AbstractMap.SimpleEntry<Object,Object>(entry.getKey(),lp.get());
+				}
+				return entry;
+			}
+			public void remove() {
+				i.remove();
+			}
+		};
+	}
+
+}
diff -r 7c768f63bbb3 -r 392105b660d7 core/src/luan/LuanTableImpl.java
--- a/core/src/luan/LuanTableImpl.java	Tue Jul 22 03:06:27 2014 +0000
+++ b/core/src/luan/LuanTableImpl.java	Tue Jul 22 06:23:13 2014 +0000
@@ -15,7 +15,7 @@
 import java.util.regex.Pattern;
 
 
-final class LuanTableImpl extends AbstractLuanTable implements LuanTable, DeepCloneable<LuanTableImpl>, LuanRepr {
+class LuanTableImpl extends AbstractLuanTable implements LuanTable, DeepCloneable<LuanTableImpl>, LuanRepr {
 	private Map<Object,Object> map = null;
 	private List<Object> list = null;
 	private LuanTable metatable = null;
@@ -140,21 +140,14 @@
 		sb.append('{');
 		boolean isFirst = true;
 		if( list != null ) {
-			boolean gotNull = false;
 			for( int i=0; i<list.size(); i++ ) {
 				Object obj = list.get(i);
-				if( obj==null ) {
-					gotNull = true;
+				if( isFirst ) {
+					isFirst = false;
 				} else {
-					if( isFirst ) {
-						isFirst = false;
-					} else {
-						sb.append(", ");
-					}
-					if( gotNull )
-						sb.append(i+1).append('=');
-					sb.append(repr(set,obj));
+					sb.append(", ");
 				}
+				sb.append(repr(set,obj));
 			}
 		}
 		if( map != null ) {
@@ -173,7 +166,7 @@
 
 	private static final Pattern namePtn = Pattern.compile("[a-zA-Z_][a-zA-Z_0-9]*");
 
-	private static String reprKey(Set<LuanTableImpl> set,Object obj) {
+	private String reprKey(Set<LuanTableImpl> set,Object obj) {
 		if( obj instanceof String ) {
 			String s = (String)obj;
 			if( namePtn.matcher(s).matches() )
@@ -182,7 +175,7 @@
 		return "[" + repr(set,obj) + "]";
 	}
 
-	private static String repr(Set<LuanTableImpl> set,Object obj) {
+	String repr(Set<LuanTableImpl> set,Object obj) {
 		if( obj instanceof LuanTableImpl ) {
 			LuanTableImpl t = (LuanTableImpl)obj;
 			return t.repr(set);
@@ -349,7 +342,7 @@
 	}
 
 	@Override public LuanTable subList(int from,int to) {
-		LuanTableImpl tbl = new LuanTableImpl();
+		LuanTableImpl tbl = shallowClone();
 		tbl.list = new ArrayList<Object>(list().subList(from-1,to-1));
 		return tbl;
 	}
diff -r 7c768f63bbb3 -r 392105b660d7 web/src/luan/modules/web/HttpLuan.java
--- a/web/src/luan/modules/web/HttpLuan.java	Tue Jul 22 03:06:27 2014 +0000
+++ b/web/src/luan/modules/web/HttpLuan.java	Tue Jul 22 06:23:13 2014 +0000
@@ -22,6 +22,7 @@
 import luan.AbstractLuanTable;
 import luan.LuanJavaFunction;
 import luan.LuanExitException;
+import luan.LuanProperty;
 import luan.DeepCloner;
 import luan.modules.PackageLuan;
 import luan.modules.IoLuan;
@@ -117,7 +118,7 @@
 	}
 
 	private LuanTable requestTable() throws NoSuchMethodException {
-		LuanTable tbl = Luan.newTable();
+		LuanTable tbl = Luan.newPropertyTable();
 		tbl.put("java",request);
 		LuanTable parameters = new NameTable() {
 
@@ -150,19 +151,21 @@
 			}
 		};
 		tbl.put( "headers", headers );
-		tbl.put( "get_method", new LuanJavaFunction(
-			HttpServletRequest.class.getMethod("getMethod"), request
-		) );
-		tbl.put( "get_servlet_path", new LuanJavaFunction(
-			HttpServletRequest.class.getMethod("getServletPath"), request
-		) );
-		tbl.put( "get_server_name", new LuanJavaFunction(
-			HttpServletRequest.class.getMethod("getServerName"), request
-		) );
-		add( tbl, "get_current_url" );
-		tbl.put( "get_remote_address", new LuanJavaFunction(
-			HttpServletRequest.class.getMethod("getRemoteAddr"), request
-		) );
+		tbl.put( "method", new LuanProperty(){ public Object get() {
+			return request.getMethod();
+		} } );
+		tbl.put( "servlet_path", new LuanProperty(){ public Object get() {
+			return request.getServletPath();
+		} } );
+		tbl.put( "server_name", new LuanProperty(){ public Object get() {
+			return request.getServerName();
+		} } );
+		tbl.put( "current_url", new LuanProperty(){ public Object get() {
+			return getCurrentURL(request);
+		} } );
+		tbl.put( "remote_address", new LuanProperty(){ public Object get() {
+			return request.getRemoteAddr();
+		} } );
 		LuanTable cookies = new AbstractLuanTable() {
 
 			@Override public final Object get(Object key) {
@@ -201,7 +204,7 @@
 	}
 
 	private LuanTable responseTable() throws NoSuchMethodException {
-		LuanTable tbl = Luan.newTable();
+		LuanTable tbl = Luan.newPropertyTable();
 		tbl.put("java",response);
 		add( tbl, "send_redirect", String.class );
 		add( tbl, "send_error", Integer.TYPE, String.class );
@@ -236,12 +239,22 @@
 			}
 		};
 		tbl.put( "headers", headers );
-		tbl.put( "set_content_type", new LuanJavaFunction(
-			HttpServletResponse.class.getMethod("setContentType",String.class), response
-		) );
-		tbl.put( "set_character_encoding", new LuanJavaFunction(
-			HttpServletResponse.class.getMethod("setCharacterEncoding",String.class), response
-		) );
+		tbl.put( "content_type", new LuanProperty(){
+			@Override public Object get() {
+				return response.getContentType();
+			}
+			@Override public boolean set(Object value) {
+				response.setContentType(string(value));  return true;
+			}
+		} );
+		tbl.put( "character_encoding", new LuanProperty(){
+			@Override public Object get() {
+				return response.getCharacterEncoding();
+			}
+			@Override public boolean set(Object value) {
+				response.setCharacterEncoding(string(value));  return true;
+			}
+		} );
 		add( tbl, "text_writer" );
 		add( tbl, "set_cookie", String.class, String.class, Boolean.TYPE, String.class );
 		add( tbl, "remove_cookie", String.class, String.class );
@@ -296,10 +309,6 @@
 		return a==null ? null : TableLuan.pack(a);
 	}
 
-	public String get_current_url() {
-		return getCurrentURL(request);
-	}
-
 	public void send_redirect(String redirectUrl)
 		throws IOException
 	{
@@ -478,5 +487,9 @@
 		}
 	};
 
-
+	private static String string(Object value) {
+		if( !(value instanceof String) )
+			throw new IllegalArgumentException("value must be string");
+		return (String)value;
+	}
 }
diff -r 7c768f63bbb3 -r 392105b660d7 web/src/luan/modules/web/web_run.luan
--- a/web/src/luan/modules/web/web_run.luan	Tue Jul 22 03:06:27 2014 +0000
+++ b/web/src/luan/modules/web/web_run.luan	Tue Jul 22 06:23:13 2014 +0000
@@ -21,7 +21,7 @@
 function service()
 	local content_type = Http.request.parameters.content_type
 	if content_type ~= nil then
-		Http.response.set_content_type(content_type)
+		Http.response.content_type = content_type
 	end
 	Io.stdout = Http.response.text_writer()
 	local code = Http.request.parameters.code