Javaのクラス定義からJSONの文字列を出力する

JSON関係の仕様書を作成するため、クラス定義からJSONの文字列を出力するプログラムを作成した。
Mapには未対応のため、ご注意ください。

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.stream.IntStream;

public class PrintJson {

    /** インデント用文字 */
    private static final String INDENT = "  ";

    /** JSONに出力する型で定義 */
    static XXXXX dto;

    public static void main(String[] args) {
        try {
            System.out.println(getJson(PrintJson.class.getDeclaredField("dto"), 1, null));
        } catch (NoSuchFieldException | SecurityException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param inputField
     *            JSON出力用のField(ジェネリック対応のため、Classではなく、Field)
     * @param level
     *            インデント用のレベル
     * @param parentField
     *            Fieldの親Field(ジェネリックの型判定用)
     * @return Fieldに該当するJSON
     */
    private static String getJson(Field inputField, int level, Field parentField) {
        StringBuilder sb = new StringBuilder();

        Class<?> inputFieldType = inputField.getType();
        Class<?> clazz = inputFieldType;
        if (inputFieldType.isArray() || isIterable(inputFieldType)) {
            sb.append("[");
            if (inputFieldType.isArray()) {
                clazz = inputFieldType.getComponentType();
            } else {
                Type type = inputField.getGenericType();
                if (type instanceof ParameterizedType) {
                    Type actualType = ((ParameterizedType) type).getActualTypeArguments()[0];
                    if (actualType instanceof Class) {
                        clazz = (Class<?>) actualType;
                    } else {
                        clazz = (Class<?>) ((ParameterizedType) parentField.getGenericType())
                                .getActualTypeArguments()[0];
                    }
                }
            }
        }
        if (clazz.isPrimitive() || (Integer.class == clazz) || (Double.class == clazz) || (Date.class == clazz)
                || (Timestamp.class == clazz) || (Long.class == clazz) || (BigDecimal.class == clazz)
                || (String.class == clazz)) {
            sb.append("\"\"");
        } else {
            sb.append("{").append("\n");

            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                sb.append(getIndent(level)).append("\"").append(field.getName()).append("\":");
                sb.append(getJson(field, level + 1, inputField)).append(",\n");
            }
            if (fields.length > 0) {
                // 最後の「,」を削除
                sb.delete(sb.length() - 2, sb.length() - 1);
            }
            sb.append(getIndent(level - 1)).append("}");
        }
        if (inputFieldType.isArray() || isIterable(inputFieldType)) {
            sb.append("]");
        }
        return sb.toString();
    }

    /**
     * @param level
     * @return level分のインデント用のスペース
     */
    private static String getIndent(int level) {
        StringBuilder sb = new StringBuilder();
        IntStream.range(0, level).forEach(i -> sb.append(INDENT));
        return sb.toString();
    }

    /**
     * @param clazz
     * @return clazzがIterableかどうか
     */
    private static boolean isIterable(Class<?> clazz) {
        if (clazz == Iterable.class) {
            return true;
        } else {
            for (Class<?> clazz1 : clazz.getInterfaces()) {
                if (isIterable(clazz1)) {
                    return true;
                }
            }
        }
        return false;
    }
}