org.dbflute.lasta.di.util.JSONSerializer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lasta-di Show documentation
Show all versions of lasta-di Show documentation
DI Container for LastaFlute, super forked from Seasar as Java8
The newest version!
/*
* Copyright 2014-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package org.dbflute.lasta.di.util;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.dbflute.lasta.di.helper.beans.BeanDesc;
import org.dbflute.lasta.di.helper.beans.PropertyDesc;
import org.dbflute.lasta.di.helper.beans.factory.BeanDescFactory;
/**
* JSON形式の文字列を解析します。 ObjectをJSON文字列へシリアライズ、JSON文字列をObjectへ評価します。
*
* @author mopemope
* @deprecated このクラスの代わりにJSONIC等を使用してください
*/
public class JSONSerializer {
private static final String COMMA = ",";
private static final String COLON = ":";
private static final String SINGLE_QUOTE = "'";
private static final String DOUBLE_QUOTE = "\"";
private static final String NULL_STRING = "null";
private static final String TRUE_STRING = "true";
private static final String FALSE_STRING = "false";
private static final String START_BRACKET = "[";
private static final String END_BRACKET = "]";
private static final String START_BRACE = "{";
private static final String END_BRACE = "}";
/**
* ObjectをJSONにシリアライズします。
*
* @param o
* シリアライズ対象{@link java.lang.Object}
* @return JSON形式の文字列
*/
public static String serialize(Object o) {
StringBuffer buf = new StringBuffer(100);
appendSerializeObject(buf, o);
return buf.toString();
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param o
* シリアライズ対象{@link java.lang.Object}
*/
public static void appendSerializeObject(StringBuffer buf, Object o) {
if (o == null) {
buf.append(JSONSerializer.NULL_STRING);
} else if (o instanceof String) {
buf.append(quote((String) o));
} else if (o instanceof Float) {
appendSerializeFloat(buf, (Float) o);
} else if (o instanceof Double) {
appendSerializeDouble(buf, (Double) o);
} else if (o instanceof Number) {
buf.append(o.toString());
} else if (o instanceof Boolean) {
appendSerializeBoolean(buf, (Boolean) o);
} else if (o instanceof Collection) {
appendSerializeArray(buf, ((Collection) o).toArray());
} else if (o instanceof Object[]) {
appendSerializeArray(buf, (Object[]) o);
} else if (o instanceof Map) {
appendSerializeMap(buf, (Map) o);
} else if (o.getClass().isArray()) {
appendSerializeObjectArray(buf, o);
} else {
appendSerializeBean(buf, o);
}
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param f
* シリアライズ対象{@link java.lang.Float}
*/
public static void appendSerializeFloat(StringBuffer buf, Float f) {
if (f.isNaN() || f.isInfinite()) {
throw new IllegalArgumentException(f.toString());
}
buf.append(f.toString());
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param d
* シリアライズ対象{@link java.lang.Double}
*/
public static void appendSerializeDouble(StringBuffer buf, Double d) {
if (d.isNaN() || d.isInfinite()) {
throw new IllegalArgumentException(d.toString());
}
buf.append(d.toString());
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param b
* シリアライズ対象{@link java.lang.Boolean}
*/
public static void appendSerializeBoolean(StringBuffer buf, Boolean b) {
if (Boolean.TRUE.equals(b)) {
buf.append(JSONSerializer.TRUE_STRING);
} else {
buf.append(JSONSerializer.FALSE_STRING);
}
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param array
* シリアライズ対象{@link java.lang.Object}配列
*/
public static void appendSerializeArray(StringBuffer buf, Object[] array) {
int length = array.length;
buf.append(JSONSerializer.START_BRACKET);
for (int i = 0; i < length; ++i) {
appendSerializeObject(buf, array[i]);
buf.append(JSONSerializer.COMMA);
}
if (length > 0) {
buf.setLength(buf.length() - 1);
}
buf.append(JSONSerializer.END_BRACKET);
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param map
* シリアライズ対象{@link java.util.Map}
*/
public static void appendSerializeMap(StringBuffer buf, Map map) {
buf.append(JSONSerializer.START_BRACE);
for (Iterator i = map.keySet().iterator(); i.hasNext();) {
String key = (String) i.next();
buf.append(quote(key) + JSONSerializer.COLON);
appendSerializeObject(buf, map.get(key));
buf.append(JSONSerializer.COMMA);
}
if (map.size() > 0) {
buf.setLength(buf.length() - 1);
}
buf.append(JSONSerializer.END_BRACE);
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param bean
* シリアライズ対象{@link java.lang.Object}
*/
public static void appendSerializeBean(StringBuffer buf, Object bean) {
buf.append(JSONSerializer.START_BRACE);
BeanDesc beanDesc = BeanDescFactory.getBeanDesc(bean.getClass());
for (int i = 0; i < beanDesc.getPropertyDescSize(); ++i) {
PropertyDesc pd = beanDesc.getPropertyDesc(i);
buf.append(pd.getPropertyName() + JSONSerializer.COLON);
appendSerializeObject(buf, pd.getValue(bean));
buf.append(JSONSerializer.COMMA);
}
if (beanDesc.getPropertyDescSize() > 0) {
buf.setLength(buf.length() - 1);
}
buf.append(JSONSerializer.END_BRACE);
}
/**
* 指定したバッファにJSONシリアライズした結果を追加します。
*
* @param buf
* {@link java.lang.StringBuffer}
* @param o
* シリアライズ対象{@link java.lang.Object}
*/
public static void appendSerializeObjectArray(StringBuffer buf, Object o) {
int length = Array.getLength(o);
buf.append(JSONSerializer.START_BRACKET);
for (int i = 0; i < length; i++) {
Object value = Array.get(o, i);
appendSerializeObject(buf, value);
buf.append(JSONSerializer.COMMA);
}
if (length > 0) {
buf.setLength(buf.length() - 1);
}
buf.append(JSONSerializer.END_BRACKET);
}
/**
* 文字列を引用付で囲みます。
*
* @param str
* 対象の文字列
* @return 引用付で囲まれた{@link java.lang.String}
*/
public static String quote(String str) {
if (str == null || str.length() == 0) {
return "\"\"";
}
char current = 0;
int len = str.length();
StringBuffer sb = new StringBuffer(len + 4);
sb.append('"');
for (int i = 0; i < len; ++i) {
current = str.charAt(i);
switch (current) {
case '\\':
case '/':
case '"':
sb.append('\\');
sb.append(current);
break;
case '\b':
sb.append("\\b");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\f':
sb.append("\\f");
break;
case '\r':
sb.append("\\r");
break;
default:
if (current < ' ') {
String t = "000" + Integer.toHexString(current);
sb.append("\\u" + t.substring(t.length() - 4));
} else {
sb.append(current);
}
}
}
sb.append('"');
return sb.toString();
}
/**
* 指定した文字列がJSONのObject形式か判断します。
*
* @param str
* 対象の文字列
* @return JSONのObject形式であればtrue、そうでなければfalse
*/
public static boolean isObject(String str) {
return str.startsWith(JSONSerializer.START_BRACE) && str.endsWith(JSONSerializer.END_BRACE);
}
/**
* 指定した文字列がJSONのArray形式か判断します。
*
* @param str
* 対象の文字列
* @return JSONのArray形式であればtrue、そうでなければfalse
*/
public static boolean isArray(String str) {
return str.startsWith(JSONSerializer.START_BRACKET) && str.endsWith(JSONSerializer.END_BRACKET);
}
/**
* 指定した文字列がJSONのString形式か判断します。
*
* @param str
* 対象の文字列
* @return JSONのString形式であればtrue、そうでなければfalse
*/
public static boolean isString(String str) {
return (str.startsWith(JSONSerializer.SINGLE_QUOTE) && str.endsWith(JSONSerializer.SINGLE_QUOTE) || str
.startsWith(JSONSerializer.DOUBLE_QUOTE) && str.endsWith(JSONSerializer.DOUBLE_QUOTE));
}
/**
* 指定したJSON文字列を評価します。
*
* @param str
* 対象の文字列
* @return 評価された{@link javac.lang.Object}
*/
public static Object eval(String str) {
if (JSONSerializer.isObject(str)) {
return JSONSerializer.evalMap(str);
} else if (JSONSerializer.isArray(str)) {
return JSONSerializer.evalArray(str);
} else if (JSONSerializer.isString(str)) {
return JSONSerializer.evalString(str);
} else {
return JSONSerializer.evalInt(str);
}
}
/**
* 指定したJSON文字列を評価します。
*
* @param str
* 対象の文字列
* @return 評価された{@link javac.util.Map}
*/
public static Map evalMap(String str) {
Map map = new HashMap();
StringBuffer buf = new StringBuffer();
String key = null;
String value = null;
boolean valueParse = false;
boolean isListedData = false;
boolean isMappedData = false;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
switch (c) {
case '{':
if (valueParse) {
String sub = str.substring(i, str.length() - 1);
int count = 0;
for (int j = 0; j < sub.length(); ++j) {
char sc = sub.charAt(j);
if (sc == '{') {
count++;
continue;
}
if (sc == '}' && count > 1) {
count--;
} else if (sc == '}' && count == 1) {
String mapStr = sub.substring(0, j + 1);
Map submap = JSONSerializer.evalMap(mapStr);
map.put(key, submap);
i = i + j;
isMappedData = true;
break;
}
}
}
break;
case '}':
break;
case '[':
if (valueParse) {
String sub = str.substring(i, str.length() - 1);
int count = 0;
for (int j = 0; j < sub.length(); ++j) {
char sc = sub.charAt(j);
if (sc == '[') {
count++;
continue;
}
if (sc == ']' && count > 1) {
count--;
} else if (sc == ']' && count == 1) {
String arrayStr = sub.substring(0, j + 1);
List list = JSONSerializer.evalArray(arrayStr);
map.put(key, list);
i = i + j;
isListedData = true;
break;
}
}
}
break;
case ']':
break;
case ':':
key = JSONSerializer.evalString(buf.toString().trim());
valueParse = true;
buf = new StringBuffer();
isListedData = false;
isMappedData = false;
break;
case ',':
if (!isListedData && !isMappedData) {
value = buf.toString().trim();
valueParse = false;
buf = new StringBuffer();
evalAndAddMap(key, value, map);
}
isListedData = false;
isMappedData = false;
break;
default:
buf.append(c);
break;
}
}
if (buf.length() > 0) {
value = buf.toString().trim();
}
if (value != null) {
evalAndAddMap(key, value, map);
}
return map;
}
/**
* 指定したJSON文字列を評価します。
*
* @param str
* 対象の文字列
* @return 評価された{@link javac.util.List}
*/
public static List evalArray(String str) {
List list = new ArrayList();
StringBuffer buf = new StringBuffer();
String value = null;
boolean isMappedData = false;
for (int i = 1; i < str.length() - 1; i++) {
char c = str.charAt(i);
switch (c) {
case '{':
String sub = str.substring(i, str.length() - 1);
int count = 0;
for (int j = 0; j < sub.length(); ++j) {
char sc = sub.charAt(j);
if (sc == '{') {
count++;
continue;
}
if (sc == '}' && count > 1) {
count--;
} else if (sc == '}' && count == 1) {
String mapStr = sub.substring(0, j + 1);
Map map = JSONSerializer.evalMap(mapStr);
list.add(map);
i = i + j;
isMappedData = true;
break;
}
}
break;
case '}':
break;
case '[':
buf.append(c);
break;
case ']':
buf.append(c);
break;
case ':':
break;
case ',':
if (!isMappedData) {
value = buf.toString().trim();
buf = new StringBuffer();
JSONSerializer.evalAndAddList(value, list);
}
isMappedData = false;
break;
default:
buf.append(c);
break;
}
}
if (buf.length() > 0) {
value = buf.toString().trim();
}
if (value != null) {
JSONSerializer.evalAndAddList(value, list);
}
return list;
}
private static void evalAndAddList(String value, List list) {
if (JSONSerializer.isObject(value)) {
list.add(JSONSerializer.evalMap(value));
} else if (JSONSerializer.isArray(value)) {
list.add(JSONSerializer.evalArray(value));
} else {
Integer intValue = evalInt(value);
if (intValue != null) {
list.add(intValue);
} else {
list.add(JSONSerializer.evalString(value));
}
}
}
private static void evalAndAddMap(String key, String value, Map map) {
if (JSONSerializer.isObject(value)) {
Map v = JSONSerializer.evalMap(value);
map.put(key, v);
} else if (JSONSerializer.isArray(value)) {
List list = JSONSerializer.evalArray(value);
map.put(key, list);
} else {
Integer intValue = evalInt(value);
if (intValue != null) {
map.put(key, intValue);
} else {
map.put(key, JSONSerializer.evalString(value));
}
}
}
/**
* 指定したJSON文字列を評価します。
*
* @param str
* 対象の文字列
* @return 評価された{@link javac.lang.String}
*/
public static String evalString(String str) {
if (JSONSerializer.isString(str)) {
return str.substring(1, str.length() - 1);
}
return str;
}
/**
* 指定したJSON文字列を評価します。
*
* @param str
* 対象の文字列
* @return 評価された{@link javac.lang.Integer}
*/
public static Integer evalInt(String str) {
try {
int i = Integer.parseInt(str);
return new Integer(i);
} catch (NumberFormatException e) {
return null;
}
}
}