001package gudusoft.gsqlparser.util.json; 002 003import gudusoft.gsqlparser.dlineage.util.BeanUtil; 004 005import java.io.Serializable; 006import java.lang.reflect.Array; 007import java.text.StringCharacterIterator; 008import java.util.LinkedHashMap; 009import java.util.List; 010import java.util.Map; 011 012@SuppressWarnings("rawtypes") 013public class JSONSerializer implements Serializable { 014 015 private static final long serialVersionUID = -947149613761603468L; 016 017 private boolean ignoreId = false; 018 019 public JSONSerializer(boolean ignoreId) { 020 this.ignoreId = ignoreId; 021 } 022 023 public JSONSerializer() { 024 } 025 026 private void check(Object obj) { 027 if (obj == null || !(obj instanceof LinkedHashMap || obj instanceof List)) { 028 throw new IllegalArgumentException("Invalid JSON structure"); 029 } 030 } 031 032 public String serialize(List list) { 033 check(list); 034 StringBuilder sb = new StringBuilder("["); 035 for (Object element : list) { 036 if (element instanceof List) 037 sb.append(serializeList((List) element)); 038 else if (element.getClass().isArray()) 039 sb.append(serializeArray(element)); 040 else if (element instanceof LinkedHashMap) 041 sb.append(serialize(BeanUtil.bean2Map(element))).append(","); 042 else 043 appendValue(sb, element); 044 } 045 String result = sb.toString(); 046 if (result.endsWith(",")) 047 result = result.substring(0, result.length() - 1); 048 return result + "]"; 049 } 050 051 public String serialize(Map map) { 052 check(map); 053 StringBuilder sb = new StringBuilder("{"); 054 for (Object k : map.keySet()) { 055 String key = (String) k; 056 if (ignoreId && "id".equals(key)) { 057 continue; 058 } 059 Object val = map.get(key); 060 if (val instanceof List) 061 sb.append("\"").append(key).append("\":[").append(serializeList((List) val)).append("],"); 062 else if (val.getClass().isArray()) 063 sb.append("\"").append(key).append("\":[").append(serializeArray(val)).append("],"); 064 else if (val instanceof LinkedHashMap) 065 sb.append("\"").append(key).append("\":").append(serialize(BeanUtil.bean2Map(val))).append(","); 066 else 067 appendEntry(sb, key, val); 068 } 069 String result = sb.toString(); 070 if (result.endsWith(",")) 071 result = result.substring(0, result.length() - 1); 072 return result + "}"; 073 } 074 075 private String serializeList(List list) { 076 StringBuilder sb = new StringBuilder(); 077 int n = list.size(); 078 for (int i = 0; i < n; i++) { 079 Object obj = list.get(i); 080 if (obj instanceof String) 081 sb.append("\"").append(escape((String) obj)).append("\""); 082 else 083 sb.append(serialize(BeanUtil.bean2Map(obj))); 084 if (i < n - 1) 085 sb.append(","); 086 } 087 return sb.toString(); 088 } 089 090 private String serializeArray(Object array) { 091 int n = Array.getLength(array); 092 StringBuilder sb = new StringBuilder(); 093 for (int i = 0; i < n; i++) { 094 Object obj = Array.get(array, i); 095 if (obj instanceof String) 096 sb.append("\"").append(escape((String) obj)).append("\""); 097 else 098 sb.append(serialize(BeanUtil.bean2Map(obj))); 099 if (i < n - 1) 100 sb.append(","); 101 } 102 return sb.toString(); 103 } 104 105 private void appendEntry(StringBuilder sb, String key, Object val) { 106 boolean quote = false; 107 if (!(val instanceof String || val instanceof Number || val instanceof Boolean)) 108 val = serialize(BeanUtil.bean2Map(val)); 109 else if (val instanceof String) { 110 val = escape((String) val); 111 quote = true; 112 } 113 sb.append("\"").append(key).append("\":").append(quote ? "\"" : "").append(val).append(quote ? "\"" : "") 114 .append(","); 115 } 116 117 private void appendValue(StringBuilder sb, Object val) { 118 boolean quote = false; 119 if (!(val instanceof String || val instanceof Integer || val instanceof Long || val instanceof Boolean)) 120 val = serialize(BeanUtil.bean2Map(val)); 121 else if (val instanceof String) { 122 val = escape((String) val); 123 quote = true; 124 } 125 sb.append(quote ? "\"" : "").append(val).append(quote ? "\"" : "").append(","); 126 } 127 128 private static String escape(String str) { 129 StringBuilder sb = new StringBuilder(); 130 StringCharacterIterator it = new StringCharacterIterator(str); 131 char ch = it.current(); 132 while (ch != StringCharacterIterator.DONE) { 133 switch (ch) { 134 case '"': 135 sb.append("\\\""); 136 break; 137 case '\t': 138 sb.append("\\t"); 139 break; 140 case '\f': 141 sb.append("\\f"); 142 break; 143 case '\n': 144 sb.append("\\n"); 145 break; 146 case '\r': 147 sb.append("\\r"); 148 break; 149 case '\\': 150 sb.append("\\\\"); 151 break; 152 case '/': 153 sb.append("\\/"); 154 break; 155 case '\b': 156 sb.append("\\b"); 157 break; 158 default: 159 sb.append(ch); 160 } 161 ch = it.next(); 162 } 163 return sb.toString(); 164 } 165}