1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.springframework.extensions.webscripts.json;
20
21 import java.io.IOException;
22 import java.io.Writer;
23 import java.util.Stack;
24
25
26
27
28
29
30
31
32
33
34 public final class JSONWriter
35 {
36 private Writer out;
37 private Stack<Boolean> stack = new Stack<Boolean>();
38
39 public JSONWriter(Writer out)
40 {
41 this.out = out;
42 stack.push(Boolean.FALSE);
43 }
44
45 public void startArray() throws IOException
46 {
47 if (stack.peek() == true) out.write(", ");
48 out.write("[");
49 stack.pop();
50 stack.push(Boolean.TRUE);
51 stack.push(Boolean.FALSE);
52 }
53
54 public void endArray() throws IOException
55 {
56 out.write("]");
57 stack.pop();
58 }
59
60 public void startObject() throws IOException
61 {
62 if (stack.peek() == true) out.write(", ");
63 out.write("{");
64 stack.pop();
65 stack.push(Boolean.TRUE);
66 stack.push(Boolean.FALSE);
67 }
68
69 public void endObject() throws IOException
70 {
71 out.write("}");
72 stack.pop();
73 }
74
75 public void startValue(String name) throws IOException
76 {
77 if (stack.peek() == true) out.write(", ");
78 out.write('"');
79 out.write(name);
80 out.write("\": ");
81 stack.pop();
82 stack.push(Boolean.TRUE);
83 stack.push(Boolean.FALSE);
84 }
85
86 public void endValue()
87 {
88 stack.pop();
89 }
90
91 public void writeValue(String name, String value) throws IOException
92 {
93 if (stack.peek() == true) out.write(", ");
94 out.write('"');
95 out.write(name);
96 out.write("\": \"");
97 out.write(encodeJSONString(value));
98 out.write('"');
99 stack.pop();
100 stack.push(Boolean.TRUE);
101 }
102
103 public void writeValue(String name, int value) throws IOException
104 {
105 if (stack.peek() == true) out.write(", ");
106 out.write('"');
107 out.write(name);
108 out.write("\": ");
109 out.write(Integer.toString(value));
110 stack.pop();
111 stack.push(Boolean.TRUE);
112 }
113
114 public void writeValue(String name, boolean value) throws IOException
115 {
116 if (stack.peek() == true) out.write(", ");
117 out.write('"');
118 out.write(name);
119 out.write("\": ");
120 out.write(Boolean.toString(value));
121 stack.pop();
122 stack.push(Boolean.TRUE);
123 }
124
125 public void writeNullValue(String name) throws IOException
126 {
127 if (stack.peek() == true) out.write(", ");
128 out.write('"');
129 out.write(name);
130 out.write("\": null");
131 stack.pop();
132 stack.push(Boolean.TRUE);
133 }
134
135 public static String encodeJSONString(final String s)
136 {
137 if (s == null || s.length() == 0)
138 {
139 return "";
140 }
141
142 StringBuilder sb = null;
143 String enc;
144 char c;
145 int len = s.length();
146 for (int i = 0; i < len; i++)
147 {
148 enc = null;
149 c = s.charAt(i);
150 switch (c)
151 {
152 case '\\':
153 enc = "\\\\";
154 break;
155 case '"':
156 enc = "\\\"";
157 break;
158 case '/':
159 enc = "\\/";
160 break;
161 case '\b':
162 enc = "\\b";
163 break;
164 case '\t':
165 enc = "\\t";
166 break;
167 case '\n':
168 enc = "\\n";
169 break;
170 case '\f':
171 enc = "\\f";
172 break;
173 case '\r':
174 enc = "\\r";
175 break;
176
177 default:
178 if (((int)c) >= 0x80)
179 {
180
181 String u = "000" + Integer.toHexString((int)c);
182 enc = "\\u" + u.substring(u.length() - 4);
183
184 }
185 break;
186 }
187
188 if (enc != null)
189 {
190 if (sb == null)
191 {
192 String soFar = s.substring(0, i);
193 sb = new StringBuilder(i + 8);
194 sb.append(soFar);
195 }
196 sb.append(enc);
197 }
198 else
199 {
200 if (sb != null)
201 {
202 sb.append(c);
203 }
204 }
205 }
206
207 if (sb == null)
208 {
209 return s;
210 }
211 else
212 {
213 return sb.toString();
214 }
215 }
216 }