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&lt;List&lt;String&gt;&gt;() {}.getType();
88  * List&lt;String&gt; target = new LinkedList&lt;String&gt;();
89  * target.add("blah");
90  *
91  * Gson gson = new Gson();
92  * String json = gson.toJson(target, listType);
93  * List&lt;String&gt; 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>&quot;versionNumber&quot;</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&lt;Collection&lt;Foo&gt;&gt;(){}.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&lt;Collection&lt;Foo&gt;&gt;(){}.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&lt;Collection&lt;Foo&gt;&gt;(){}.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 nullif {@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&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
834    * </pre>
835    * @return an object of type T from the string. Returns {@code nullif {@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 nullif {@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&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
888    * </pre>
889    * @return an object of type T from the json. Returns {@code nullif {@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 nullif {@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&lt;Collection&lt;Foo&gt;&gt;(){}.getType();
992    * </pre>
993    * @return an object of type T from the json. Returns {@code nullif {@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