001package org.javasimon.console.json;
002
003import org.javasimon.console.text.BaseStringifier;
004import org.javasimon.console.text.Stringifier;
005import org.javasimon.console.text.StringifierFactory;
006
007/**
008 * Value formatter for JSON responses.
009 *
010 * @author gquintana
011 * @author raipc
012 */
013public class JsonStringifierFactory extends StringifierFactory {
014
015        @Override
016        protected Stringifier registerNullStringifier() {
017                return registerNullStringifier("\"\"");
018        }
019
020        @Override
021        protected Stringifier<String> registerStringStringifier(Stringifier nullStringifier) {
022                Stringifier<String> stringStringifier = new BaseStringifier<String>(nullStringifier) {
023                        @Override
024                        protected String doToString(String string) {
025                                if (string.isEmpty()) {
026                                        return "\"\"";
027                                }
028                                final int len = string.length();
029                                final StringBuilder sb = new StringBuilder(len + 6).append('"');
030                                for (int i = 0; i < len; i++) {
031                                        char c = string.charAt(i);
032                                        switch (c) {
033                                                case '\\':
034                                                case '"':
035                                                        sb.append('\\');
036                                                        sb.append(c);
037                                                        break;
038                                                case '/':
039                                                        sb.append("\\/");
040                                                        break;
041                                                case '\b':
042                                                        sb.append("\\b");
043                                                        break;
044                                                case '\t':
045                                                        sb.append("\\t");
046                                                        break;
047                                                case '\n':
048                                                        sb.append("\\n");
049                                                        break;
050                                                case '\f':
051                                                        sb.append("\\f");
052                                                        break;
053                                                case '\r':
054                                                        sb.append("\\r");
055                                                        break;
056                                                default:
057                                                        if (c < ' ') {
058                                                                sb.append("\\u");
059                                                                String hexString = Integer.toHexString(c);
060                                                                for (int j = hexString.length(); j < 4; j++) {
061                                                                        sb.append('0');
062                                                                }
063                                                                sb.append(hexString);
064                                                        } else {
065                                                                sb.append(c);
066                                                        }
067                                        }
068                                }
069                                return sb.append('"').toString();
070                        }
071                };
072                compositeStringifier.add(String.class, stringStringifier);
073                return stringStringifier;
074        }
075}