1 package net.minidev.json.reader;
2
3 import java.io.IOException;
4 import java.math.BigDecimal;
5 import java.math.BigInteger;
6 import java.util.Date;
7 import java.util.LinkedList;
8 import java.util.Map;
9 import java.util.concurrent.ConcurrentHashMap;
10 import net.minidev.json.JSONAware;
11 import net.minidev.json.JSONAwareEx;
12 import net.minidev.json.JSONStreamAware;
13 import net.minidev.json.JSONStreamAwareEx;
14 import net.minidev.json.JSONStyle;
15 import net.minidev.json.JSONValue;
16
17 public class JsonWriter {
18 private ConcurrentHashMap<Class<?>, JsonWriterI<?>> data;
19 private LinkedList<WriterByInterface> writerInterfaces;
20
21 public JsonWriter() {
22 data = new ConcurrentHashMap<Class<?>, JsonWriterI<?>>();
23 writerInterfaces = new LinkedList<WriterByInterface>();
24 init();
25 }
26
27
36 @SuppressWarnings({ "rawtypes", "unchecked" })
37 public <T> void remapField(Class<T> type, String fromJava, String toJson) {
38 JsonWriterI map = this.getWrite(type);
39 if (!(map instanceof BeansWriterASMRemap)) {
40 map = new BeansWriterASMRemap();
41 registerWriter(map, type);
42 }
43 ((BeansWriterASMRemap) map).renameField(fromJava, toJson);
44 }
45
46 static class WriterByInterface {
47 public Class<?> _interface;
48 public JsonWriterI<?> _writer;
49
50 public WriterByInterface(Class<?> _interface, JsonWriterI<?> _writer) {
51 this._interface = _interface;
52 this._writer = _writer;
53 }
54 }
55
56
61 @SuppressWarnings("rawtypes")
62 public JsonWriterI getWriterByInterface(Class<?> clazz) {
63 for (WriterByInterface w : writerInterfaces) {
64 if (w._interface.isAssignableFrom(clazz))
65 return w._writer;
66 }
67 return null;
68 }
69
70 @SuppressWarnings("rawtypes")
71 public JsonWriterI getWrite(Class cls) {
72 return data.get(cls);
73 }
74
75 final static public JsonWriterI<JSONStreamAwareEx> JSONStreamAwareWriter = new JsonWriterI<JSONStreamAwareEx>() {
76 public <E extends JSONStreamAwareEx> void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
77 value.writeJSONString(out);
78 }
79 };
80
81 final static public JsonWriterI<JSONStreamAwareEx> JSONStreamAwareExWriter = new JsonWriterI<JSONStreamAwareEx>() {
82 public <E extends JSONStreamAwareEx> void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
83 value.writeJSONString(out, compression);
84 }
85 };
86
87 final static public JsonWriterI<JSONAwareEx> JSONJSONAwareExWriter = new JsonWriterI<JSONAwareEx>() {
88 public <E extends JSONAwareEx> void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
89 out.append(value.toJSONString(compression));
90 }
91 };
92
93 final static public JsonWriterI<JSONAware> JSONJSONAwareWriter = new JsonWriterI<JSONAware>() {
94 public <E extends JSONAware> void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
95 out.append(value.toJSONString());
96 }
97 };
98
99 final static public JsonWriterI<Iterable<? extends Object>> JSONIterableWriter = new JsonWriterI<Iterable<? extends Object>>() {
100 public <E extends Iterable<? extends Object>> void writeJSONString(E list, Appendable out, JSONStyle compression) throws IOException {
101 boolean first = true;
102 compression.arrayStart(out);
103 for (Object value : list) {
104 if (first) {
105 first = false;
106 compression.arrayfirstObject(out);
107 } else {
108 compression.arrayNextElm(out);
109 }
110 if (value == null)
111 out.append("null");
112 else
113 JSONValue.writeJSONString(value, out, compression);
114 compression.arrayObjectEnd(out);
115 }
116 compression.arrayStop(out);
117 }
118 };
119
120 final static public JsonWriterI<Enum<?>> EnumWriter = new JsonWriterI<Enum<?>>() {
121 public <E extends Enum<?>> void writeJSONString(E value, Appendable out, JSONStyle compression) throws IOException {
122 @SuppressWarnings("rawtypes")
123 String s = ((Enum) value).name();
124 compression.writeString(out, s);
125 }
126 };
127
128 final static public JsonWriterI<Map<String, ? extends Object>> JSONMapWriter = new JsonWriterI<Map<String, ? extends Object>>() {
129 public <E extends Map<String, ? extends Object>> void writeJSONString(E map, Appendable out, JSONStyle compression) throws IOException {
130 boolean first = true;
131 compression.objectStart(out);
132
135 for (Map.Entry<?, ?> entry : map.entrySet()) {
136 Object v = entry.getValue();
137 if (v == null && compression.ignoreNull())
138 continue;
139 if (first) {
140 compression.objectFirstStart(out);
141 first = false;
142 } else {
143 compression.objectNext(out);
144 }
145 JsonWriter.writeJSONKV(entry.getKey().toString(), v, out, compression);
146
147 }
148 compression.objectStop(out);
149 }
150 };
151
152
157 final static public JsonWriterI<Object> beansWriterASM = new BeansWriterASM();
158
159
162 final static public JsonWriterI<Object> beansWriter = new BeansWriter();
163
164
167 final static public JsonWriterI<Object> arrayWriter = new ArrayWriter();
168
169
172 final static public JsonWriterI<Object> toStringWriter = new JsonWriterI<Object>() {
173 public void writeJSONString(Object value, Appendable out, JSONStyle compression) throws IOException {
174 out.append(value.toString());
175 }
176 };
177
178 public void init() {
179 registerWriter(new JsonWriterI<String>() {
180 public void writeJSONString(String value, Appendable out, JSONStyle compression) throws IOException {
181 compression.writeString(out, (String) value);
182 }
183 }, String.class);
184
185 registerWriter(new JsonWriterI<Double>() {
186 public void writeJSONString(Double value, Appendable out, JSONStyle compression) throws IOException {
187 if (value.isInfinite())
188 out.append("null");
189 else
190 out.append(value.toString());
191 }
192 }, Double.class);
193
194 registerWriter(new JsonWriterI<Date>() {
195 public void writeJSONString(Date value, Appendable out, JSONStyle compression) throws IOException {
196 out.append('"');
197 JSONValue.escape(value.toString(), out, compression);
198 out.append('"');
199 }
200 }, Date.class);
201
202 registerWriter(new JsonWriterI<Float>() {
203 public void writeJSONString(Float value, Appendable out, JSONStyle compression) throws IOException {
204 if (value.isInfinite())
205 out.append("null");
206 else
207 out.append(value.toString());
208 }
209 }, Float.class);
210
211 registerWriter(toStringWriter, Integer.class, Long.class, Byte.class, Short.class, BigInteger.class, BigDecimal.class);
212 registerWriter(toStringWriter, Boolean.class);
213
214
217
218 registerWriter(new JsonWriterI<int[]>() {
219 public void writeJSONString(int[] value, Appendable out, JSONStyle compression) throws IOException {
220 boolean needSep = false;
221 compression.arrayStart(out);
222 for (int b : value) {
223 if (needSep)
224 compression.objectNext(out);
225 else
226 needSep = true;
227 out.append(Integer.toString(b));
228 }
229 compression.arrayStop(out);
230 }
231 }, int[].class);
232
233 registerWriter(new JsonWriterI<short[]>() {
234 public void writeJSONString(short[] value, Appendable out, JSONStyle compression) throws IOException {
235 boolean needSep = false;
236 compression.arrayStart(out);
237 for (short b : value) {
238 if (needSep)
239 compression.objectNext(out);
240 else
241 needSep = true;
242 out.append(Short.toString(b));
243 }
244 compression.arrayStop(out);
245 }
246 }, short[].class);
247
248 registerWriter(new JsonWriterI<long[]>() {
249 public void writeJSONString(long[] value, Appendable out, JSONStyle compression) throws IOException {
250 boolean needSep = false;
251 compression.arrayStart(out);
252 for (long b : value) {
253 if (needSep)
254 compression.objectNext(out);
255 else
256 needSep = true;
257 out.append(Long.toString(b));
258 }
259 compression.arrayStop(out);
260 }
261 }, long[].class);
262
263 registerWriter(new JsonWriterI<float[]>() {
264 public void writeJSONString(float[] value, Appendable out, JSONStyle compression) throws IOException {
265 boolean needSep = false;
266 compression.arrayStart(out);
267 for (float b : value) {
268 if (needSep)
269 compression.objectNext(out);
270 else
271 needSep = true;
272 out.append(Float.toString(b));
273 }
274 compression.arrayStop(out);
275 }
276 }, float[].class);
277
278 registerWriter(new JsonWriterI<double[]>() {
279 public void writeJSONString(double[] value, Appendable out, JSONStyle compression) throws IOException {
280 boolean needSep = false;
281 compression.arrayStart(out);
282 for (double b : value) {
283 if (needSep)
284 compression.objectNext(out);
285 else
286 needSep = true;
287 out.append(Double.toString(b));
288 }
289 compression.arrayStop(out);
290 }
291 }, double[].class);
292
293 registerWriter(new JsonWriterI<boolean[]>() {
294 public void writeJSONString(boolean[] value, Appendable out, JSONStyle compression) throws IOException {
295 boolean needSep = false;
296 compression.arrayStart(out);
297 for (boolean b : value) {
298 if (needSep)
299 compression.objectNext(out);
300 else
301 needSep = true;
302 out.append(Boolean.toString(b));
303 }
304 compression.arrayStop(out);
305 }
306 }, boolean[].class);
307
308 registerWriterInterface(JSONStreamAwareEx.class, JsonWriter.JSONStreamAwareExWriter);
309 registerWriterInterface(JSONStreamAware.class, JsonWriter.JSONStreamAwareWriter);
310 registerWriterInterface(JSONAwareEx.class, JsonWriter.JSONJSONAwareExWriter);
311 registerWriterInterface(JSONAware.class, JsonWriter.JSONJSONAwareWriter);
312 registerWriterInterface(Map.class, JsonWriter.JSONMapWriter);
313 registerWriterInterface(Iterable.class, JsonWriter.JSONIterableWriter);
314 registerWriterInterface(Enum.class, JsonWriter.EnumWriter);
315 registerWriterInterface(Number.class, JsonWriter.toStringWriter);
316 }
317
318
324 public void addInterfaceWriterFirst(Class<?> interFace, JsonWriterI<?> writer) {
325 registerWriterInterfaceFirst(interFace, writer);
326 }
327
328
334 public void addInterfaceWriterLast(Class<?> interFace, JsonWriterI<?> writer) {
335 registerWriterInterfaceLast(interFace, writer);
336 }
337
338
343 public void registerWriterInterfaceLast(Class<?> interFace, JsonWriterI<?> writer) {
344 writerInterfaces.addLast(new WriterByInterface(interFace, writer));
345 }
346
347
352 public void registerWriterInterfaceFirst(Class<?> interFace, JsonWriterI<?> writer) {
353 writerInterfaces.addFirst(new WriterByInterface(interFace, writer));
354 }
355
356
361 public void registerWriterInterface(Class<?> interFace, JsonWriterI<?> writer) {
362 registerWriterInterfaceLast(interFace, writer);
363 }
364
365
370 public <T> void registerWriter(JsonWriterI<T> writer, Class<?>... cls) {
371 for (Class<?> c : cls)
372 data.put(c, writer);
373 }
374
375
378 public static void writeJSONKV(String key, Object value, Appendable out, JSONStyle compression) throws IOException {
379 if (key == null)
380 out.append("null");
381 else if (!compression.mustProtectKey(key))
382 out.append(key);
383 else {
384 out.append('"');
385 JSONValue.escape(key, out, compression);
386 out.append('"');
387 }
388 compression.objectEndOfKey(out);
389 if (value instanceof String) {
390 compression.writeString(out, (String) value);
391 } else
392 JSONValue.writeJSONString(value, out, compression);
393 compression.objectElmStop(out);
394 }
395 }
396