1 /*
2 * Copyright (C) 2008 Google Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.google.gson;
18
19 import java.io.EOFException;
20 import java.io.IOException;
21 import java.io.Reader;
22 import java.io.StringReader;
23 import java.io.StringWriter;
24 import java.io.Writer;
25 import java.lang.reflect.Type;
26 import java.math.BigDecimal;
27 import java.math.BigInteger;
28 import java.text.DateFormat;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.concurrent.ConcurrentHashMap;
35 import java.util.concurrent.atomic.AtomicLong;
36 import java.util.concurrent.atomic.AtomicLongArray;
37
38 import com.google.gson.internal.ConstructorConstructor;
39 import com.google.gson.internal.Excluder;
40 import com.google.gson.internal.GsonBuildConfig;
41 import com.google.gson.internal.Primitives;
42 import com.google.gson.internal.Streams;
43 import com.google.gson.internal.bind.ArrayTypeAdapter;
44 import com.google.gson.internal.bind.CollectionTypeAdapterFactory;
45 import com.google.gson.internal.bind.DateTypeAdapter;
46 import com.google.gson.internal.bind.JsonAdapterAnnotationTypeAdapterFactory;
47 import com.google.gson.internal.bind.JsonTreeReader;
48 import com.google.gson.internal.bind.JsonTreeWriter;
49 import com.google.gson.internal.bind.MapTypeAdapterFactory;
50 import com.google.gson.internal.bind.ObjectTypeAdapter;
51 import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory;
52 import com.google.gson.internal.bind.SqlDateTypeAdapter;
53 import com.google.gson.internal.bind.TimeTypeAdapter;
54 import com.google.gson.internal.bind.TypeAdapters;
55 import com.google.gson.reflect.TypeToken;
56 import com.google.gson.stream.JsonReader;
57 import com.google.gson.stream.JsonToken;
58 import com.google.gson.stream.JsonWriter;
59 import com.google.gson.stream.MalformedJsonException;
60
61 /**
62 * This is the main class for using Gson. Gson is typically used by first constructing a
63 * Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)}
64 * methods on it. Gson instances are Thread-safe so you can reuse them freely across multiple
65 * threads.
66 *
67 * <p>You can create a Gson instance by invoking {@code new Gson()} if the default configuration
68 * is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various
69 * configuration options such as versioning support, pretty printing, custom
70 * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p>
71 *
72 * <p>Here is an example of how Gson is used for a simple Class:
73 *
74 * <pre>
75 * Gson gson = new Gson(); // Or use new GsonBuilder().create();
76 * MyType target = new MyType();
77 * String json = gson.toJson(target); // serializes target to Json
78 * MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
79 * </pre></p>
80 *
81 * <p>If the object that your are serializing/deserializing is a {@code ParameterizedType}
82 * (i.e. contains at least one type parameter and may be an array) then you must use the
83 * {@link #toJson(Object, Type)} or {@link #fromJson(String, Type)} method. Here is an
84 * example for serializing and deserializing a {@code ParameterizedType}:
85 *
86 * <pre>
87 * Type listType = new TypeToken<List<String>>() {}.getType();
88 * List<String> target = new LinkedList<String>();
89 * target.add("blah");
90 *
91 * Gson gson = new Gson();
92 * String json = gson.toJson(target, listType);
93 * List<String> target2 = gson.fromJson(json, listType);
94 * </pre></p>
95 *
96 * <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
97 * for a more complete set of examples.</p>
98 *
99 * @see com.google.gson.reflect.TypeToken
100 *
101 * @author Inderjeet Singh
102 * @author Joel Leitch
103 * @author Jesse Wilson
104 */
105 public final class Gson {
106 static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
107 static final boolean DEFAULT_LENIENT = false;
108 static final boolean DEFAULT_PRETTY_PRINT = false;
109 static final boolean DEFAULT_ESCAPE_HTML = true;
110 static final boolean DEFAULT_SERIALIZE_NULLS = false;
111 static final boolean DEFAULT_COMPLEX_MAP_KEYS = false;
112 static final boolean DEFAULT_SPECIALIZE_FLOAT_VALUES = false;
113
114 private static final TypeToken<?> NULL_KEY_SURROGATE = TypeToken.get(Object.class);
115 private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n";
116
117 /**
118 * This thread local guards against reentrant calls to getAdapter(). In
119 * certain object graphs, creating an adapter for a type may recursively
120 * require an adapter for the same type! Without intervention, the recursive
121 * lookup would stack overflow. We cheat by returning a proxy type adapter.
122 * The proxy is wired up once the initial adapter has been created.
123 */
124 private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls
125 = new ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>>();
126
127 private final Map<TypeToken<?>, TypeAdapter<?>> typeTokenCache = new ConcurrentHashMap<TypeToken<?>, TypeAdapter<?>>();
128
129 private final ConstructorConstructor constructorConstructor;
130 private final JsonAdapterAnnotationTypeAdapterFactory jsonAdapterFactory;
131
132 final List<TypeAdapterFactory> factories;
133
134 final Excluder excluder;
135 final FieldNamingStrategy fieldNamingStrategy;
136 final Map<Type, InstanceCreator<?>> instanceCreators;
137 final boolean serializeNulls;
138 final boolean complexMapKeySerialization;
139 final boolean generateNonExecutableJson;
140 final boolean htmlSafe;
141 final boolean prettyPrinting;
142 final boolean lenient;
143 final boolean serializeSpecialFloatingPointValues;
144 final String datePattern;
145 final int dateStyle;
146 final int timeStyle;
147 final LongSerializationPolicy longSerializationPolicy;
148 final List<TypeAdapterFactory> builderFactories;
149 final List<TypeAdapterFactory> builderHierarchyFactories;
150
151 /**
152 * Constructs a Gson object with default configuration. The default configuration has the
153 * following settings:
154 * <ul>
155 * <li>The JSON generated by <code>toJson</code> methods is in compact representation. This
156 * means that all the unneeded white-space is removed. You can change this behavior with
157 * {@link GsonBuilder#setPrettyPrinting()}. </li>
158 * <li>The generated JSON omits all the fields that are null. Note that nulls in arrays are
159 * kept as is since an array is an ordered list. Moreover, if a field is not null, but its
160 * generated JSON is empty, the field is kept. You can configure Gson to serialize null values
161 * by setting {@link GsonBuilder#serializeNulls()}.</li>
162 * <li>Gson provides default serialization and deserialization for Enums, {@link Map},
163 * {@link java.net.URL}, {@link java.net.URI}, {@link java.util.Locale}, {@link java.util.Date},
164 * {@link java.math.BigDecimal}, and {@link java.math.BigInteger} classes. If you would prefer
165 * to change the default representation, you can do so by registering a type adapter through
166 * {@link GsonBuilder#registerTypeAdapter(Type, Object)}. </li>
167 * <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. This format
168 * ignores the millisecond portion of the date during serialization. You can change
169 * this by invoking {@link GsonBuilder#setDateFormat(int)} or
170 * {@link GsonBuilder#setDateFormat(String)}. </li>
171 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Expose} annotation.
172 * You can enable Gson to serialize/deserialize only those fields marked with this annotation
173 * through {@link GsonBuilder#excludeFieldsWithoutExposeAnnotation()}. </li>
174 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Since} annotation. You
175 * can enable Gson to use this annotation through {@link GsonBuilder#setVersion(double)}.</li>
176 * <li>The default field naming policy for the output Json is same as in Java. So, a Java class
177 * field <code>versionNumber</code> will be output as <code>"versionNumber"</code> in
178 * Json. The same rules are applied for mapping incoming Json to the Java classes. You can
179 * change this policy through {@link GsonBuilder#setFieldNamingPolicy(FieldNamingPolicy)}.</li>
180 * <li>By default, Gson excludes <code>transient</code> or <code>static</code> fields from
181 * consideration for serialization and deserialization. You can change this behavior through
182 * {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.</li>
183 * </ul>
184 */
185 public Gson() {
186 this(Excluder.DEFAULT, FieldNamingPolicy.IDENTITY,
187 Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS,
188 DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML,
189 DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES,
190 LongSerializationPolicy.DEFAULT, null, DateFormat.DEFAULT, DateFormat.DEFAULT,
191 Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(),
192 Collections.<TypeAdapterFactory>emptyList());
193 }
194
195 Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy,
196 Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls,
197 boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe,
198 boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues,
199 LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle,
200 int timeStyle, List<TypeAdapterFactory> builderFactories,
201 List<TypeAdapterFactory> builderHierarchyFactories,
202 List<TypeAdapterFactory> factoriesToBeAdded) {
203 this.excluder = excluder;
204 this.fieldNamingStrategy = fieldNamingStrategy;
205 this.instanceCreators = instanceCreators;
206 this.constructorConstructor = new ConstructorConstructor(instanceCreators);
207 this.serializeNulls = serializeNulls;
208 this.complexMapKeySerialization = complexMapKeySerialization;
209 this.generateNonExecutableJson = generateNonExecutableGson;
210 this.htmlSafe = htmlSafe;
211 this.prettyPrinting = prettyPrinting;
212 this.lenient = lenient;
213 this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
214 this.longSerializationPolicy = longSerializationPolicy;
215 this.datePattern = datePattern;
216 this.dateStyle = dateStyle;
217 this.timeStyle = timeStyle;
218 this.builderFactories = builderFactories;
219 this.builderHierarchyFactories = builderHierarchyFactories;
220
221 List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>();
222
223 // built-in type adapters that cannot be overridden
224 factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
225 factories.add(ObjectTypeAdapter.FACTORY);
226
227 // the excluder must precede all adapters that handle user-defined types
228 factories.add(excluder);
229
230 // users' type adapters
231 factories.addAll(factoriesToBeAdded);
232
233 // type adapters for basic platform types
234 factories.add(TypeAdapters.STRING_FACTORY);
235 factories.add(TypeAdapters.INTEGER_FACTORY);
236 factories.add(TypeAdapters.BOOLEAN_FACTORY);
237 factories.add(TypeAdapters.BYTE_FACTORY);
238 factories.add(TypeAdapters.SHORT_FACTORY);
239 TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy);
240 factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter));
241 factories.add(TypeAdapters.newFactory(double.class, Double.class,
242 doubleAdapter(serializeSpecialFloatingPointValues)));
243 factories.add(TypeAdapters.newFactory(float.class, Float.class,
244 floatAdapter(serializeSpecialFloatingPointValues)));
245 factories.add(TypeAdapters.NUMBER_FACTORY);
246 factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY);
247 factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY);
248 factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter)));
249 factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter)));
250 factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY);
251 factories.add(TypeAdapters.CHARACTER_FACTORY);
252 factories.add(TypeAdapters.STRING_BUILDER_FACTORY);
253 factories.add(TypeAdapters.STRING_BUFFER_FACTORY);
254 factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL));
255 factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER));
256 factories.add(TypeAdapters.URL_FACTORY);
257 factories.add(TypeAdapters.URI_FACTORY);
258 factories.add(TypeAdapters.UUID_FACTORY);
259 factories.add(TypeAdapters.CURRENCY_FACTORY);
260 factories.add(TypeAdapters.LOCALE_FACTORY);
261 factories.add(TypeAdapters.INET_ADDRESS_FACTORY);
262 factories.add(TypeAdapters.BIT_SET_FACTORY);
263 factories.add(DateTypeAdapter.FACTORY);
264 factories.add(TypeAdapters.CALENDAR_FACTORY);
265 factories.add(TimeTypeAdapter.FACTORY);
266 factories.add(SqlDateTypeAdapter.FACTORY);
267 factories.add(TypeAdapters.TIMESTAMP_FACTORY);
268 factories.add(ArrayTypeAdapter.FACTORY);
269 factories.add(TypeAdapters.CLASS_FACTORY);
270
271 // type adapters for composite and user-defined types
272 factories.add(new CollectionTypeAdapterFactory(constructorConstructor));
273 factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization));
274 this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor);
275 factories.add(jsonAdapterFactory);
276 factories.add(TypeAdapters.ENUM_FACTORY);
277 factories.add(new ReflectiveTypeAdapterFactory(
278 constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory));
279
280 this.factories = Collections.unmodifiableList(factories);
281 }
282
283 /**
284 * Returns a new GsonBuilder containing all custom factories and configuration used by the current
285 * instance.
286 *
287 * @return a GsonBuilder instance.
288 */
289 public GsonBuilder newBuilder() {
290 return new GsonBuilder(this);
291 }
292
293 public Excluder excluder() {
294 return excluder;
295 }
296
297 public FieldNamingStrategy fieldNamingStrategy() {
298 return fieldNamingStrategy;
299 }
300
301 public boolean serializeNulls() {
302 return serializeNulls;
303 }
304
305 public boolean htmlSafe() {
306 return htmlSafe;
307 }
308
309 private TypeAdapter<Number> doubleAdapter(boolean serializeSpecialFloatingPointValues) {
310 if (serializeSpecialFloatingPointValues) {
311 return TypeAdapters.DOUBLE;
312 }
313 return new TypeAdapter<Number>() {
314 @Override public Double read(JsonReader in) throws IOException {
315 if (in.peek() == JsonToken.NULL) {
316 in.nextNull();
317 return null;
318 }
319 return in.nextDouble();
320 }
321 @Override public void write(JsonWriter out, Number value) throws IOException {
322 if (value == null) {
323 out.nullValue();
324 return;
325 }
326 double doubleValue = value.doubleValue();
327 checkValidFloatingPoint(doubleValue);
328 out.value(value);
329 }
330 };
331 }
332
333 private TypeAdapter<Number> floatAdapter(boolean serializeSpecialFloatingPointValues) {
334 if (serializeSpecialFloatingPointValues) {
335 return TypeAdapters.FLOAT;
336 }
337 return new TypeAdapter<Number>() {
338 @Override public Float read(JsonReader in) throws IOException {
339 if (in.peek() == JsonToken.NULL) {
340 in.nextNull();
341 return null;
342 }
343 return (float) in.nextDouble();
344 }
345 @Override public void write(JsonWriter out, Number value) throws IOException {
346 if (value == null) {
347 out.nullValue();
348 return;
349 }
350 float floatValue = value.floatValue();
351 checkValidFloatingPoint(floatValue);
352 out.value(value);
353 }
354 };
355 }
356
357 static void checkValidFloatingPoint(double value) {
358 if (Double.isNaN(value) || Double.isInfinite(value)) {
359 throw new IllegalArgumentException(value
360 + " is not a valid double value as per JSON specification. To override this"
361 + " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.");
362 }
363 }
364
365 private static TypeAdapter<Number> longAdapter(LongSerializationPolicy longSerializationPolicy) {
366 if (longSerializationPolicy == LongSerializationPolicy.DEFAULT) {
367 return TypeAdapters.LONG;
368 }
369 return new TypeAdapter<Number>() {
370 @Override public Number read(JsonReader in) throws IOException {
371 if (in.peek() == JsonToken.NULL) {
372 in.nextNull();
373 return null;
374 }
375 return in.nextLong();
376 }
377 @Override public void write(JsonWriter out, Number value) throws IOException {
378 if (value == null) {
379 out.nullValue();
380 return;
381 }
382 out.value(value.toString());
383 }
384 };
385 }
386
387 private static TypeAdapter<AtomicLong> atomicLongAdapter(final TypeAdapter<Number> longAdapter) {
388 return new TypeAdapter<AtomicLong>() {
389 @Override public void write(JsonWriter out, AtomicLong value) throws IOException {
390 longAdapter.write(out, value.get());
391 }
392 @Override public AtomicLong read(JsonReader in) throws IOException {
393 Number value = longAdapter.read(in);
394 return new AtomicLong(value.longValue());
395 }
396 }.nullSafe();
397 }
398
399 private static TypeAdapter<AtomicLongArray> atomicLongArrayAdapter(final TypeAdapter<Number> longAdapter) {
400 return new TypeAdapter<AtomicLongArray>() {
401 @Override public void write(JsonWriter out, AtomicLongArray value) throws IOException {
402 out.beginArray();
403 for (int i = 0, length = value.length(); i < length; i++) {
404 longAdapter.write(out, value.get(i));
405 }
406 out.endArray();
407 }
408 @Override public AtomicLongArray read(JsonReader in) throws IOException {
409 List<Long> list = new ArrayList<Long>();
410 in.beginArray();
411 while (in.hasNext()) {
412 long value = longAdapter.read(in).longValue();
413 list.add(value);
414 }
415 in.endArray();
416 int length = list.size();
417 AtomicLongArray array = new AtomicLongArray(length);
418 for (int i = 0; i < length; ++i) {
419 array.set(i, list.get(i));
420 }
421 return array;
422 }
423 }.nullSafe();
424 }
425
426 /**
427 * Returns the type adapter for {@code} type.
428 *
429 * @throws IllegalArgumentException if this GSON cannot serialize and
430 * deserialize {@code type}.
431 */
432 @SuppressWarnings("unchecked")
433 public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) {
434 TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type);
435 if (cached != null) {
436 return (TypeAdapter<T>) cached;
437 }
438
439 Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get();
440 boolean requiresThreadLocalCleanup = false;
441 if (threadCalls == null) {
442 threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>();
443 calls.set(threadCalls);
444 requiresThreadLocalCleanup = true;
445 }
446
447 // the key and value type parameters always agree
448 FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type);
449 if (ongoingCall != null) {
450 return ongoingCall;
451 }
452
453 try {
454 FutureTypeAdapter<T> call = new FutureTypeAdapter<T>();
455 threadCalls.put(type, call);
456
457 for (TypeAdapterFactory factory : factories) {
458 TypeAdapter<T> candidate = factory.create(this, type);
459 if (candidate != null) {
460 call.setDelegate(candidate);
461 typeTokenCache.put(type, candidate);
462 return candidate;
463 }
464 }
465 throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type);
466 } finally {
467 threadCalls.remove(type);
468
469 if (requiresThreadLocalCleanup) {
470 calls.remove();
471 }
472 }
473 }
474
475 /**
476 * This method is used to get an alternate type adapter for the specified type. This is used
477 * to access a type adapter that is overridden by a {@link TypeAdapterFactory} that you
478 * may have registered. This features is typically used when you want to register a type
479 * adapter that does a little bit of work but then delegates further processing to the Gson
480 * default type adapter. Here is an example:
481 * <p>Let's say we want to write a type adapter that counts the number of objects being read
482 * from or written to JSON. We can achieve this by writing a type adapter factory that uses
483 * the <code>getDelegateAdapter</code> method:
484 * <pre> {@code
485 * class StatsTypeAdapterFactory implements TypeAdapterFactory {
486 * public int numReads = 0;
487 * public int numWrites = 0;
488 * public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
489 * final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
490 * return new TypeAdapter<T>() {
491 * public void write(JsonWriter out, T value) throws IOException {
492 * ++numWrites;
493 * delegate.write(out, value);
494 * }
495 * public T read(JsonReader in) throws IOException {
496 * ++numReads;
497 * return delegate.read(in);
498 * }
499 * };
500 * }
501 * }
502 * } </pre>
503 * This factory can now be used like this:
504 * <pre> {@code
505 * StatsTypeAdapterFactory stats = new StatsTypeAdapterFactory();
506 * Gson gson = new GsonBuilder().registerTypeAdapterFactory(stats).create();
507 * // Call gson.toJson() and fromJson methods on objects
508 * System.out.println("Num JSON reads" + stats.numReads);
509 * System.out.println("Num JSON writes" + stats.numWrites);
510 * }</pre>
511 * Note that this call will skip all factories registered before {@code skipPast}. In case of
512 * multiple TypeAdapterFactories registered it is up to the caller of this function to insure
513 * that the order of registration does not prevent this method from reaching a factory they
514 * would expect to reply from this call.
515 * Note that since you can not override type adapter factories for String and Java primitive
516 * types, our stats factory will not count the number of String or primitives that will be
517 * read or written.
518 * @param skipPast The type adapter factory that needs to be skipped while searching for
519 * a matching type adapter. In most cases, you should just pass <i>this</i> (the type adapter
520 * factory from where {@link #getDelegateAdapter} method is being invoked).
521 * @param type Type for which the delegate adapter is being searched for.
522 *
523 * @since 2.2
524 */
525 public <T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) {
526 // Hack. If the skipPast factory isn't registered, assume the factory is being requested via
527 // our @JsonAdapter annotation.
528 if (!factories.contains(skipPast)) {
529 skipPast = jsonAdapterFactory;
530 }
531
532 boolean skipPastFound = false;
533 for (TypeAdapterFactory factory : factories) {
534 if (!skipPastFound) {
535 if (factory == skipPast) {
536 skipPastFound = true;
537 }
538 continue;
539 }
540
541 TypeAdapter<T> candidate = factory.create(this, type);
542 if (candidate != null) {
543 return candidate;
544 }
545 }
546 throw new IllegalArgumentException("GSON cannot serialize " + type);
547 }
548
549 /**
550 * Returns the type adapter for {@code} type.
551 *
552 * @throws IllegalArgumentException if this GSON cannot serialize and
553 * deserialize {@code type}.
554 */
555 public <T> TypeAdapter<T> getAdapter(Class<T> type) {
556 return getAdapter(TypeToken.get(type));
557 }
558
559 /**
560 * This method serializes the specified object into its equivalent representation as a tree of
561 * {@link JsonElement}s. This method should be used when the specified object is not a generic
562 * type. This method uses {@link Class#getClass()} to get the type for the specified object, but
563 * the {@code getClass()} loses the generic type information because of the Type Erasure feature
564 * of Java. Note that this method works fine if the any of the object fields are of generic type,
565 * just the object itself should not be of a generic type. If the object is of generic type, use
566 * {@link #toJsonTree(Object, Type)} instead.
567 *
568 * @param src the object for which Json representation is to be created setting for Gson
569 * @return Json representation of {@code src}.
570 * @since 1.4
571 */
572 public JsonElement toJsonTree(Object src) {
573 if (src == null) {
574 return JsonNull.INSTANCE;
575 }
576 return toJsonTree(src, src.getClass());
577 }
578
579 /**
580 * This method serializes the specified object, including those of generic types, into its
581 * equivalent representation as a tree of {@link JsonElement}s. This method must be used if the
582 * specified object is a generic type. For non-generic objects, use {@link #toJsonTree(Object)}
583 * instead.
584 *
585 * @param src the object for which JSON representation is to be created
586 * @param typeOfSrc The specific genericized type of src. You can obtain
587 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
588 * to get the type for {@code Collection<Foo>}, you should use:
589 * <pre>
590 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
591 * </pre>
592 * @return Json representation of {@code src}
593 * @since 1.4
594 */
595 public JsonElement toJsonTree(Object src, Type typeOfSrc) {
596 JsonTreeWriter writer = new JsonTreeWriter();
597 toJson(src, typeOfSrc, writer);
598 return writer.get();
599 }
600
601 /**
602 * This method serializes the specified object into its equivalent Json representation.
603 * This method should be used when the specified object is not a generic type. This method uses
604 * {@link Class#getClass()} to get the type for the specified object, but the
605 * {@code getClass()} loses the generic type information because of the Type Erasure feature
606 * of Java. Note that this method works fine if the any of the object fields are of generic type,
607 * just the object itself should not be of a generic type. If the object is of generic type, use
608 * {@link #toJson(Object, Type)} instead. If you want to write out the object to a
609 * {@link Writer}, use {@link #toJson(Object, Appendable)} instead.
610 *
611 * @param src the object for which Json representation is to be created setting for Gson
612 * @return Json representation of {@code src}.
613 */
614 public String toJson(Object src) {
615 if (src == null) {
616 return toJson(JsonNull.INSTANCE);
617 }
618 return toJson(src, src.getClass());
619 }
620
621 /**
622 * This method serializes the specified object, including those of generic types, into its
623 * equivalent Json representation. This method must be used if the specified object is a generic
624 * type. For non-generic objects, use {@link #toJson(Object)} instead. If you want to write out
625 * the object to a {@link Appendable}, use {@link #toJson(Object, Type, Appendable)} instead.
626 *
627 * @param src the object for which JSON representation is to be created
628 * @param typeOfSrc The specific genericized type of src. You can obtain
629 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
630 * to get the type for {@code Collection<Foo>}, you should use:
631 * <pre>
632 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
633 * </pre>
634 * @return Json representation of {@code src}
635 */
636 public String toJson(Object src, Type typeOfSrc) {
637 StringWriter writer = new StringWriter();
638 toJson(src, typeOfSrc, writer);
639 return writer.toString();
640 }
641
642 /**
643 * This method serializes the specified object into its equivalent Json representation.
644 * This method should be used when the specified object is not a generic type. This method uses
645 * {@link Class#getClass()} to get the type for the specified object, but the
646 * {@code getClass()} loses the generic type information because of the Type Erasure feature
647 * of Java. Note that this method works fine if the any of the object fields are of generic type,
648 * just the object itself should not be of a generic type. If the object is of generic type, use
649 * {@link #toJson(Object, Type, Appendable)} instead.
650 *
651 * @param src the object for which Json representation is to be created setting for Gson
652 * @param writer Writer to which the Json representation needs to be written
653 * @throws JsonIOException if there was a problem writing to the writer
654 * @since 1.2
655 */
656 public void toJson(Object src, Appendable writer) throws JsonIOException {
657 if (src != null) {
658 toJson(src, src.getClass(), writer);
659 } else {
660 toJson(JsonNull.INSTANCE, writer);
661 }
662 }
663
664 /**
665 * This method serializes the specified object, including those of generic types, into its
666 * equivalent Json representation. This method must be used if the specified object is a generic
667 * type. For non-generic objects, use {@link #toJson(Object, Appendable)} instead.
668 *
669 * @param src the object for which JSON representation is to be created
670 * @param typeOfSrc The specific genericized type of src. You can obtain
671 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
672 * to get the type for {@code Collection<Foo>}, you should use:
673 * <pre>
674 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
675 * </pre>
676 * @param writer Writer to which the Json representation of src needs to be written.
677 * @throws JsonIOException if there was a problem writing to the writer
678 * @since 1.2
679 */
680 public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {
681 try {
682 JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));
683 toJson(src, typeOfSrc, jsonWriter);
684 } catch (IOException e) {
685 throw new JsonIOException(e);
686 }
687 }
688
689 /**
690 * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
691 * {@code writer}.
692 * @throws JsonIOException if there was a problem writing to the writer
693 */
694 @SuppressWarnings("unchecked")
695 public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
696 TypeAdapter<?> adapter = getAdapter(TypeToken.get(typeOfSrc));
697 boolean oldLenient = writer.isLenient();
698 writer.setLenient(true);
699 boolean oldHtmlSafe = writer.isHtmlSafe();
700 writer.setHtmlSafe(htmlSafe);
701 boolean oldSerializeNulls = writer.getSerializeNulls();
702 writer.setSerializeNulls(serializeNulls);
703 try {
704 ((TypeAdapter<Object>) adapter).write(writer, src);
705 } catch (IOException e) {
706 throw new JsonIOException(e);
707 } catch (AssertionError e) {
708 AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
709 error.initCause(e);
710 throw error;
711 } finally {
712 writer.setLenient(oldLenient);
713 writer.setHtmlSafe(oldHtmlSafe);
714 writer.setSerializeNulls(oldSerializeNulls);
715 }
716 }
717
718 /**
719 * Converts a tree of {@link JsonElement}s into its equivalent JSON representation.
720 *
721 * @param jsonElement root of a tree of {@link JsonElement}s
722 * @return JSON String representation of the tree
723 * @since 1.4
724 */
725 public String toJson(JsonElement jsonElement) {
726 StringWriter writer = new StringWriter();
727 toJson(jsonElement, writer);
728 return writer.toString();
729 }
730
731 /**
732 * Writes out the equivalent JSON for a tree of {@link JsonElement}s.
733 *
734 * @param jsonElement root of a tree of {@link JsonElement}s
735 * @param writer Writer to which the Json representation needs to be written
736 * @throws JsonIOException if there was a problem writing to the writer
737 * @since 1.4
738 */
739 public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOException {
740 try {
741 JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer));
742 toJson(jsonElement, jsonWriter);
743 } catch (IOException e) {
744 throw new JsonIOException(e);
745 }
746 }
747
748 /**
749 * Returns a new JSON writer configured for the settings on this Gson instance.
750 */
751 public JsonWriter newJsonWriter(Writer writer) throws IOException {
752 if (generateNonExecutableJson) {
753 writer.write(JSON_NON_EXECUTABLE_PREFIX);
754 }
755 JsonWriter jsonWriter = new JsonWriter(writer);
756 if (prettyPrinting) {
757 jsonWriter.setIndent(" ");
758 }
759 jsonWriter.setSerializeNulls(serializeNulls);
760 return jsonWriter;
761 }
762
763 /**
764 * Returns a new JSON reader configured for the settings on this Gson instance.
765 */
766 public JsonReader newJsonReader(Reader reader) {
767 JsonReader jsonReader = new JsonReader(reader);
768 jsonReader.setLenient(lenient);
769 return jsonReader;
770 }
771
772 /**
773 * Writes the JSON for {@code jsonElement} to {@code writer}.
774 * @throws JsonIOException if there was a problem writing to the writer
775 */
776 public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {
777 boolean oldLenient = writer.isLenient();
778 writer.setLenient(true);
779 boolean oldHtmlSafe = writer.isHtmlSafe();
780 writer.setHtmlSafe(htmlSafe);
781 boolean oldSerializeNulls = writer.getSerializeNulls();
782 writer.setSerializeNulls(serializeNulls);
783 try {
784 Streams.write(jsonElement, writer);
785 } catch (IOException e) {
786 throw new JsonIOException(e);
787 } catch (AssertionError e) {
788 AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
789 error.initCause(e);
790 throw error;
791 } finally {
792 writer.setLenient(oldLenient);
793 writer.setHtmlSafe(oldHtmlSafe);
794 writer.setSerializeNulls(oldSerializeNulls);
795 }
796 }
797
798 /**
799 * This method deserializes the specified Json into an object of the specified class. It is not
800 * suitable to use if the specified class is a generic type since it will not have the generic
801 * type information because of the Type Erasure feature of Java. Therefore, this method should not
802 * be used if the desired type is a generic type. Note that this method works fine if the any of
803 * the fields of the specified object are generics, just the object itself should not be a
804 * generic type. For the cases when the object is of generic type, invoke
805 * {@link #fromJson(String, Type)}. If you have the Json in a {@link Reader} instead of
806 * a String, use {@link #fromJson(Reader, Class)} instead.
807 *
808 * @param <T> the type of the desired object
809 * @param json the string from which the object is to be deserialized
810 * @param classOfT the class of T
811 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null}
812 * or if {@code json} is empty.
813 * @throws JsonSyntaxException if json is not a valid representation for an object of type
814 * classOfT
815 */
816 public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException {
817 Object object = fromJson(json, (Type) classOfT);
818 return Primitives.wrap(classOfT).cast(object);
819 }
820
821 /**
822 * This method deserializes the specified Json into an object of the specified type. This method
823 * is useful if the specified object is a generic type. For non-generic objects, use
824 * {@link #fromJson(String, Class)} instead. If you have the Json in a {@link Reader} instead of
825 * a String, use {@link #fromJson(Reader, Type)} instead.
826 *
827 * @param <T> the type of the desired object
828 * @param json the string from which the object is to be deserialized
829 * @param typeOfT The specific genericized type of src. You can obtain this type by using the
830 * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
831 * {@code Collection<Foo>}, you should use:
832 * <pre>
833 * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
834 * </pre>
835 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null}
836 * or if {@code json} is empty.
837 * @throws JsonParseException if json is not a valid representation for an object of type typeOfT
838 * @throws JsonSyntaxException if json is not a valid representation for an object of type
839 */
840 @SuppressWarnings("unchecked")
841 public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
842 if (json == null) {
843 return null;
844 }
845 StringReader reader = new StringReader(json);
846 T target = (T) fromJson(reader, typeOfT);
847 return target;
848 }
849
850 /**
851 * This method deserializes the Json read from the specified reader into an object of the
852 * specified class. It is not suitable to use if the specified class is a generic type since it
853 * will not have the generic type information because of the Type Erasure feature of Java.
854 * Therefore, this method should not be used if the desired type is a generic type. Note that
855 * this method works fine if the any of the fields of the specified object are generics, just the
856 * object itself should not be a generic type. For the cases when the object is of generic type,
857 * invoke {@link #fromJson(Reader, Type)}. If you have the Json in a String form instead of a
858 * {@link Reader}, use {@link #fromJson(String, Class)} instead.
859 *
860 * @param <T> the type of the desired object
861 * @param json the reader producing the Json from which the object is to be deserialized.
862 * @param classOfT the class of T
863 * @return an object of type T from the string. Returns {@code null} if {@code json} is at EOF.
864 * @throws JsonIOException if there was a problem reading from the Reader
865 * @throws JsonSyntaxException if json is not a valid representation for an object of type
866 * @since 1.2
867 */
868 public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
869 JsonReader jsonReader = newJsonReader(json);
870 Object object = fromJson(jsonReader, classOfT);
871 assertFullConsumption(object, jsonReader);
872 return Primitives.wrap(classOfT).cast(object);
873 }
874
875 /**
876 * This method deserializes the Json read from the specified reader into an object of the
877 * specified type. This method is useful if the specified object is a generic type. For
878 * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the Json in a
879 * String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead.
880 *
881 * @param <T> the type of the desired object
882 * @param json the reader producing Json from which the object is to be deserialized
883 * @param typeOfT The specific genericized type of src. You can obtain this type by using the
884 * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
885 * {@code Collection<Foo>}, you should use:
886 * <pre>
887 * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
888 * </pre>
889 * @return an object of type T from the json. Returns {@code null} if {@code json} is at EOF.
890 * @throws JsonIOException if there was a problem reading from the Reader
891 * @throws JsonSyntaxException if json is not a valid representation for an object of type
892 * @since 1.2
893 */
894 @SuppressWarnings("unchecked")
895 public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
896 JsonReader jsonReader = newJsonReader(json);
897 T object = (T) fromJson(jsonReader, typeOfT);
898 assertFullConsumption(object, jsonReader);
899 return object;
900 }
901
902 private static void assertFullConsumption(Object obj, JsonReader reader) {
903 try {
904 if (obj != null && reader.peek() != JsonToken.END_DOCUMENT) {
905 throw new JsonIOException("JSON document was not fully consumed.");
906 }
907 } catch (MalformedJsonException e) {
908 throw new JsonSyntaxException(e);
909 } catch (IOException e) {
910 throw new JsonIOException(e);
911 }
912 }
913
914 /**
915 * Reads the next JSON value from {@code reader} and convert it to an object
916 * of type {@code typeOfT}. Returns {@code null}, if the {@code reader} is at EOF.
917 * Since Type is not parameterized by T, this method is type unsafe and should be used carefully
918 *
919 * @throws JsonIOException if there was a problem writing to the Reader
920 * @throws JsonSyntaxException if json is not a valid representation for an object of type
921 */
922 @SuppressWarnings("unchecked")
923 public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
924 boolean isEmpty = true;
925 boolean oldLenient = reader.isLenient();
926 reader.setLenient(true);
927 try {
928 reader.peek();
929 isEmpty = false;
930 TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
931 TypeAdapter<T> typeAdapter = getAdapter(typeToken);
932 T object = typeAdapter.read(reader);
933 return object;
934 } catch (EOFException e) {
935 /*
936 * For compatibility with JSON 1.5 and earlier, we return null for empty
937 * documents instead of throwing.
938 */
939 if (isEmpty) {
940 return null;
941 }
942 throw new JsonSyntaxException(e);
943 } catch (IllegalStateException e) {
944 throw new JsonSyntaxException(e);
945 } catch (IOException e) {
946 // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
947 throw new JsonSyntaxException(e);
948 } catch (AssertionError e) {
949 AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage());
950 error.initCause(e);
951 throw error;
952 } finally {
953 reader.setLenient(oldLenient);
954 }
955 }
956
957 /**
958 * This method deserializes the Json read from the specified parse tree into an object of the
959 * specified type. It is not suitable to use if the specified class is a generic type since it
960 * will not have the generic type information because of the Type Erasure feature of Java.
961 * Therefore, this method should not be used if the desired type is a generic type. Note that
962 * this method works fine if the any of the fields of the specified object are generics, just the
963 * object itself should not be a generic type. For the cases when the object is of generic type,
964 * invoke {@link #fromJson(JsonElement, Type)}.
965 * @param <T> the type of the desired object
966 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to
967 * be deserialized
968 * @param classOfT The class of T
969 * @return an object of type T from the json. Returns {@code null} if {@code json} is {@code null}
970 * or if {@code json} is empty.
971 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT
972 * @since 1.3
973 */
974 public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException {
975 Object object = fromJson(json, (Type) classOfT);
976 return Primitives.wrap(classOfT).cast(object);
977 }
978
979 /**
980 * This method deserializes the Json read from the specified parse tree into an object of the
981 * specified type. This method is useful if the specified object is a generic type. For
982 * non-generic objects, use {@link #fromJson(JsonElement, Class)} instead.
983 *
984 * @param <T> the type of the desired object
985 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to
986 * be deserialized
987 * @param typeOfT The specific genericized type of src. You can obtain this type by using the
988 * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
989 * {@code Collection<Foo>}, you should use:
990 * <pre>
991 * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
992 * </pre>
993 * @return an object of type T from the json. Returns {@code null} if {@code json} is {@code null}
994 * or if {@code json} is empty.
995 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT
996 * @since 1.3
997 */
998 @SuppressWarnings("unchecked")
999 public <T> T fromJson(JsonElement json, Type typeOfT) throws JsonSyntaxException {
1000 if (json == null) {
1001 return null;
1002 }
1003 return (T) fromJson(new JsonTreeReader(json), typeOfT);
1004 }
1005
1006 static class FutureTypeAdapter<T> extends TypeAdapter<T> {
1007 private TypeAdapter<T> delegate;
1008
1009 public void setDelegate(TypeAdapter<T> typeAdapter) {
1010 if (delegate != null) {
1011 throw new AssertionError();
1012 }
1013 delegate = typeAdapter;
1014 }
1015
1016 @Override public T read(JsonReader in) throws IOException {
1017 if (delegate == null) {
1018 throw new IllegalStateException();
1019 }
1020 return delegate.read(in);
1021 }
1022
1023 @Override public void write(JsonWriter out, T value) throws IOException {
1024 if (delegate == null) {
1025 throw new IllegalStateException();
1026 }
1027 delegate.write(out, value);
1028 }
1029 }
1030
1031 @Override
1032 public String toString() {
1033 return new StringBuilder("{serializeNulls:")
1034 .append(serializeNulls)
1035 .append(",factories:").append(factories)
1036 .append(",instanceCreators:").append(constructorConstructor)
1037 .append("}")
1038 .toString();
1039 }
1040 }
1041