view core/src/luan/LuanException.java @ 547:0be287ab0309

add lucene/Versioning and simplify Lucene fn names
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 15 Jun 2015 01:22:58 -0600
parents f99c79b0b426
children f1601a4ce1aa
line wrap: on
line source

package luan;

import java.io.StringWriter;
import java.io.PrintWriter;


public final class LuanException extends Exception implements DeepCloneable {
	private LuanTable table = new LuanTable();

	private LuanException(String msg,Throwable cause) {
		super(msg,cause);
	}

	LuanException(LuanBit bit,Object msg) throws LuanException {
		this( bit.luan.toString(msg), msg instanceof Throwable ? (Throwable)msg : null );
		table.rawPut( "java", this );
		table.rawPut( "message", msg );
		table.rawPut( "message_string", bit.luan.toString(msg) );
		for( StackTraceElement ste : bit.stackTrace() ) {
			LuanTable tbl = new LuanTable();
			tbl.rawPut( "source", ste.call.source.name );
			tbl.rawPut( "line", ste.call.lineNumber() );
			tbl.rawPut( "call_to", ste.fnName );
			table.rawPut( table.rawLength() + 1, tbl );
		}
		LuanTable metatable = new LuanTable();
		table.setMetatable(metatable);
		try {
			table.rawPut( "throw", new LuanJavaFunction(
				LuanException.class.getMethod( "throwThis" ), this
			) );
			metatable.rawPut( "__to_string", new LuanJavaFunction(
				LuanException.class.getMethod( "__to_string", LuanTable.class ), null
			) );
		} catch(NoSuchMethodException e) {
			throw new RuntimeException(e);
		}
	}

	@Override public LuanException shallowClone() {
		return new LuanException(getMessage(),getCause());
	}

	@Override public void deepenClone(DeepCloneable dc,DeepCloner cloner) {
		LuanException clone = (LuanException)dc;
		clone.table = (LuanTable)cloner.get(table);
	}

	public LuanTable table() {
		return table;
	}

	public void throwThis() throws LuanException {
		throw this;
	}

	public String getFullMessage() {
		return __to_string(table);
	}

	public static String __to_string(LuanTable table) {
		StringBuilder buf = new StringBuilder();

		Object msg = table.rawGet("message");
		String msgStr = (String)table.rawGet("message_string");
		buf.append( msgStr );

		for( int i = table.rawLength(); i>=1; i-- ) {
			LuanTable tbl = (LuanTable)table.rawGet(i);
			buf.append( "\n\t" ).append( tbl.rawGet("source") ).append( " line " ).append( tbl.rawGet("line") );
			Object callTo = tbl.rawGet("call_to");
			if( callTo != null )
				buf.append( " in call to '" ).append( callTo ).append( "'" );
		}

		if( msg instanceof Throwable ) {
			buf.append( "\nCaused by: " );
			Throwable cause = (Throwable)msg;
			StringWriter sw = new StringWriter();
			cause.printStackTrace(new PrintWriter(sw));
			buf.append( sw );
		}

		return buf.toString();
	}

}