view src/goodjava/json/JsonToString.java @ 1412:4ba0377afa3e

minor
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 02 Oct 2019 12:25:06 -0600
parents 27efb1fcbcb5
children 59fd2e8b1b9d
line wrap: on
line source

package goodjava.json;

import java.util.List;
import java.util.Map;
import java.util.Iterator;


public class JsonToString {

	public static final class JsonException extends RuntimeException {
		private JsonException(String msg) {
			super(msg);
		}
	}

	public static String toString(Object obj) throws JsonException {
		StringBuilder sb = new StringBuilder();
		new JsonToString().toString(obj,sb,0);
		sb.append('\n');
		return sb.toString();
	}

	public static String toCompressedString(Object obj) throws JsonException {
		StringBuilder sb = new StringBuilder();
		JsonToString jts = new JsonToString() {
			void indent(StringBuilder sb,int indented) {}
		};
		jts.toString(obj,sb,0);
		return sb.toString();
	}

	private void toString(Object obj,StringBuilder sb,int indented) throws JsonException {
		if( obj == null || obj instanceof Boolean || obj instanceof Number ) {
			sb.append(obj);
			return;
		}
		if( obj instanceof String ) {
			toString((String)obj,sb);
			return;
		}
		if( obj instanceof List ) {
			toString((List)obj,sb,indented);
			return;
		}
		if( obj instanceof Map ) {
			toString((Map)obj,sb,indented);
			return;
		}
		throw new JsonException("can't handle type "+obj.getClass().getName());
	}

	private static void toString(final String s,StringBuilder sb) {
		sb.append('"');
		for( int i=0; i<s.length(); i++ ) {
			char c = s.charAt(i);
			switch(c) {
			case '"':
				sb.append("\\\"");
				break;
			case '\\':
				sb.append("\\\\");
				break;
			case '\b':
				sb.append("\\b");
				break;
			case '\f':
				sb.append("\\f");
				break;
			case '\n':
				sb.append("\\n");
				break;
			case '\r':
				sb.append("\\r");
				break;
			case '\t':
				sb.append("\\t");
				break;
			default:
				sb.append(c);
			}
		}
		sb.append('"');
	}

	public static String javascriptEncode(String s) {
		StringBuilder sb = new StringBuilder();
		for( int i=0; i<s.length(); i++ ) {
			char c = s.charAt(i);
			switch(c) {
			case '"':
				sb.append("\\\"");
				break;
			case '\'':  // added for javascript
				sb.append("\\'");
				break;
			case '\\':
				sb.append("\\\\");
				break;
			case '\b':
				sb.append("\\b");
				break;
			case '\f':
				sb.append("\\f");
				break;
			case '\n':
				sb.append("\\n");
				break;
			case '\r':
				sb.append("\\r");
				break;
			case '\t':
				sb.append("\\t");
				break;
			default:
				sb.append(c);
			}
		}
		return sb.toString();
	}

	private void toString(List list,StringBuilder sb,int indented) {
		sb.append('[');
		if( !list.isEmpty() ) {
			indent(sb,indented+1);
			toString(list.get(0),sb,indented+1);
			for( int i=1; i<list.size(); i++ ) {
				sb.append(", ");
				toString(list.get(i),sb,indented+1);
			}
			indent(sb,indented);
		}
		sb.append(']');
		return;
	}

	private void toString(Map map,StringBuilder sb,int indented) throws JsonException {
		sb.append('{');
		if( !map.isEmpty() ) {
			Iterator<Map.Entry> i = map.entrySet().iterator();
			indent(sb,indented+1);
			toString(i.next(),sb,indented+1);
			while( i.hasNext() ) {
				sb.append(',');
				indent(sb,indented+1);
				toString(i.next(),sb,indented+1);
			}
			indent(sb,indented);
		}
		sb.append('}');
	}

	private void toString(Map.Entry entry,StringBuilder sb,int indented) throws JsonException {
		Object key = entry.getKey();
		if( !(key instanceof String) )
			throw new JsonException("table keys must be strings");
		toString((String)key,sb);
		sb.append(": ");
		toString(entry.getValue(),sb,indented);
	}

	void indent(StringBuilder sb,int indented) {
		sb.append('\n');
		for( int i=0; i<indented; i++ ) {
			sb.append('\t');
		}
	}

	private JsonToString() {}
}