Remove trailing whitespace
[unical.git] / gson / com / google / gson / internal / bind / TypeAdapters.java
1 /*
2 * Copyright (C) 2011 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.internal.bind;
18
19 import com.google.gson.TypeAdapterFactory;
20 import java.io.IOException;
21 import java.math.BigDecimal;
22 import java.math.BigInteger;
23 import java.net.InetAddress;
24 import java.net.URI;
25 import java.net.URISyntaxException;
26 import java.net.URL;
27 import java.sql.Timestamp;
28 import java.util.BitSet;
29 import java.util.Calendar;
30 import java.util.Date;
31 import java.util.GregorianCalendar;
32 import java.util.HashMap;
33 import java.util.Locale;
34 import java.util.Map;
35 import java.util.StringTokenizer;
36 import java.util.UUID;
37
38 import com.google.gson.Gson;
39 import com.google.gson.JsonArray;
40 import com.google.gson.JsonElement;
41 import com.google.gson.JsonIOException;
42 import com.google.gson.JsonNull;
43 import com.google.gson.JsonObject;
44 import com.google.gson.JsonPrimitive;
45 import com.google.gson.JsonSyntaxException;
46 import com.google.gson.TypeAdapter;
47 import com.google.gson.annotations.SerializedName;
48 import com.google.gson.internal.LazilyParsedNumber;
49 import com.google.gson.reflect.TypeToken;
50 import com.google.gson.stream.JsonReader;
51 import com.google.gson.stream.JsonToken;
52 import com.google.gson.stream.JsonWriter;
53
54 /**
55 * Type adapters for basic types.
56 */
57 public final class TypeAdapters {
58 private TypeAdapters() {}
59
60 @SuppressWarnings("rawtypes")
61 public static final TypeAdapter<Class> CLASS = new TypeAdapter<Class>() {
62 @Override
63 public void write(JsonWriter out, Class value) throws IOException {
64 if (value == null) {
65 out.nullValue();
66 } else {
67 throw new UnsupportedOperationException("Attempted to serialize java.lang.Class: "
68 + value.getName() + ". Forgot to register a type adapter?");
69 }
70 }
71 @Override
72 public Class read(JsonReader in) throws IOException {
73 if (in.peek() == JsonToken.NULL) {
74 in.nextNull();
75 return null;
76 } else {
77 throw new UnsupportedOperationException(
78 "Attempted to deserialize a java.lang.Class. Forgot to register a type adapter?");
79 }
80 }
81 };
82 public static final TypeAdapterFactory CLASS_FACTORY = newFactory(Class.class, CLASS);
83
84 public static final TypeAdapter<BitSet> BIT_SET = new TypeAdapter<BitSet>() {
85 public BitSet read(JsonReader in) throws IOException {
86 if (in.peek() == JsonToken.NULL) {
87 in.nextNull();
88 return null;
89 }
90
91 BitSet bitset = new BitSet();
92 in.beginArray();
93 int i = 0;
94 JsonToken tokenType = in.peek();
95 while (tokenType != JsonToken.END_ARRAY) {
96 boolean set;
97 switch (tokenType) {
98 case NUMBER:
99 set = in.nextInt() != 0;
100 break;
101 case BOOLEAN:
102 set = in.nextBoolean();
103 break;
104 case STRING:
105 String stringValue = in.nextString();
106 try {
107 set = Integer.parseInt(stringValue) != 0;
108 } catch (NumberFormatException e) {
109 throw new JsonSyntaxException(
110 "Error: Expecting: bitset number value (1, 0), Found: " + stringValue);
111 }
112 break;
113 default:
114 throw new JsonSyntaxException("Invalid bitset value type: " + tokenType);
115 }
116 if (set) {
117 bitset.set(i);
118 }
119 ++i;
120 tokenType = in.peek();
121 }
122 in.endArray();
123 return bitset;
124 }
125
126 public void write(JsonWriter out, BitSet src) throws IOException {
127 if (src == null) {
128 out.nullValue();
129 return;
130 }
131
132 out.beginArray();
133 for (int i = 0; i < src.length(); i++) {
134 int value = (src.get(i)) ? 1 : 0;
135 out.value(value);
136 }
137 out.endArray();
138 }
139 };
140
141 public static final TypeAdapterFactory BIT_SET_FACTORY = newFactory(BitSet.class, BIT_SET);
142
143 public static final TypeAdapter<Boolean> BOOLEAN = new TypeAdapter<Boolean>() {
144 @Override
145 public Boolean read(JsonReader in) throws IOException {
146 if (in.peek() == JsonToken.NULL) {
147 in.nextNull();
148 return null;
149 } else if (in.peek() == JsonToken.STRING) {
150 // support strings for compatibility with GSON 1.7
151 return Boolean.parseBoolean(in.nextString());
152 }
153 return in.nextBoolean();
154 }
155 @Override
156 public void write(JsonWriter out, Boolean value) throws IOException {
157 if (value == null) {
158 out.nullValue();
159 return;
160 }
161 out.value(value);
162 }
163 };
164
165 /**
166 * Writes a boolean as a string. Useful for map keys, where booleans aren't
167 * otherwise permitted.
168 */
169 public static final TypeAdapter<Boolean> BOOLEAN_AS_STRING = new TypeAdapter<Boolean>() {
170 @Override public Boolean read(JsonReader in) throws IOException {
171 if (in.peek() == JsonToken.NULL) {
172 in.nextNull();
173 return null;
174 }
175 return Boolean.valueOf(in.nextString());
176 }
177
178 @Override public void write(JsonWriter out, Boolean value) throws IOException {
179 out.value(value == null ? "null" : value.toString());
180 }
181 };
182
183 public static final TypeAdapterFactory BOOLEAN_FACTORY
184 = newFactory(boolean.class, Boolean.class, BOOLEAN);
185
186 public static final TypeAdapter<Number> BYTE = new TypeAdapter<Number>() {
187 @Override
188 public Number read(JsonReader in) throws IOException {
189 if (in.peek() == JsonToken.NULL) {
190 in.nextNull();
191 return null;
192 }
193 try {
194 int intValue = in.nextInt();
195 return (byte) intValue;
196 } catch (NumberFormatException e) {
197 throw new JsonSyntaxException(e);
198 }
199 }
200 @Override
201 public void write(JsonWriter out, Number value) throws IOException {
202 out.value(value);
203 }
204 };
205
206 public static final TypeAdapterFactory BYTE_FACTORY
207 = newFactory(byte.class, Byte.class, BYTE);
208
209 public static final TypeAdapter<Number> SHORT = new TypeAdapter<Number>() {
210 @Override
211 public Number read(JsonReader in) throws IOException {
212 if (in.peek() == JsonToken.NULL) {
213 in.nextNull();
214 return null;
215 }
216 try {
217 return (short) in.nextInt();
218 } catch (NumberFormatException e) {
219 throw new JsonSyntaxException(e);
220 }
221 }
222 @Override
223 public void write(JsonWriter out, Number value) throws IOException {
224 out.value(value);
225 }
226 };
227
228 public static final TypeAdapterFactory SHORT_FACTORY
229 = newFactory(short.class, Short.class, SHORT);
230
231 public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() {
232 @Override
233 public Number read(JsonReader in) throws IOException {
234 if (in.peek() == JsonToken.NULL) {
235 in.nextNull();
236 return null;
237 }
238 try {
239 return in.nextInt();
240 } catch (NumberFormatException e) {
241 throw new JsonSyntaxException(e);
242 }
243 }
244 @Override
245 public void write(JsonWriter out, Number value) throws IOException {
246 out.value(value);
247 }
248 };
249
250 public static final TypeAdapterFactory INTEGER_FACTORY
251 = newFactory(int.class, Integer.class, INTEGER);
252
253 public static final TypeAdapter<Number> LONG = new TypeAdapter<Number>() {
254 @Override
255 public Number read(JsonReader in) throws IOException {
256 if (in.peek() == JsonToken.NULL) {
257 in.nextNull();
258 return null;
259 }
260 try {
261 return in.nextLong();
262 } catch (NumberFormatException e) {
263 throw new JsonSyntaxException(e);
264 }
265 }
266 @Override
267 public void write(JsonWriter out, Number value) throws IOException {
268 out.value(value);
269 }
270 };
271
272 public static final TypeAdapter<Number> FLOAT = new TypeAdapter<Number>() {
273 @Override
274 public Number read(JsonReader in) throws IOException {
275 if (in.peek() == JsonToken.NULL) {
276 in.nextNull();
277 return null;
278 }
279 return (float) in.nextDouble();
280 }
281 @Override
282 public void write(JsonWriter out, Number value) throws IOException {
283 out.value(value);
284 }
285 };
286
287 public static final TypeAdapter<Number> DOUBLE = new TypeAdapter<Number>() {
288 @Override
289 public Number read(JsonReader in) throws IOException {
290 if (in.peek() == JsonToken.NULL) {
291 in.nextNull();
292 return null;
293 }
294 return in.nextDouble();
295 }
296 @Override
297 public void write(JsonWriter out, Number value) throws IOException {
298 out.value(value);
299 }
300 };
301
302 public static final TypeAdapter<Number> NUMBER = new TypeAdapter<Number>() {
303 @Override
304 public Number read(JsonReader in) throws IOException {
305 JsonToken jsonToken = in.peek();
306 switch (jsonToken) {
307 case NULL:
308 in.nextNull();
309 return null;
310 case NUMBER:
311 return new LazilyParsedNumber(in.nextString());
312 default:
313 throw new JsonSyntaxException("Expecting number, got: " + jsonToken);
314 }
315 }
316 @Override
317 public void write(JsonWriter out, Number value) throws IOException {
318 out.value(value);
319 }
320 };
321
322 public static final TypeAdapterFactory NUMBER_FACTORY = newFactory(Number.class, NUMBER);
323
324 public static final TypeAdapter<Character> CHARACTER = new TypeAdapter<Character>() {
325 @Override
326 public Character read(JsonReader in) throws IOException {
327 if (in.peek() == JsonToken.NULL) {
328 in.nextNull();
329 return null;
330 }
331 String str = in.nextString();
332 if (str.length() != 1) {
333 throw new JsonSyntaxException("Expecting character, got: " + str);
334 }
335 return str.charAt(0);
336 }
337 @Override
338 public void write(JsonWriter out, Character value) throws IOException {
339 out.value(value == null ? null : String.valueOf(value));
340 }
341 };
342
343 public static final TypeAdapterFactory CHARACTER_FACTORY
344 = newFactory(char.class, Character.class, CHARACTER);
345
346 public static final TypeAdapter<String> STRING = new TypeAdapter<String>() {
347 @Override
348 public String read(JsonReader in) throws IOException {
349 JsonToken peek = in.peek();
350 if (peek == JsonToken.NULL) {
351 in.nextNull();
352 return null;
353 }
354 /* coerce booleans to strings for backwards compatibility */
355 if (peek == JsonToken.BOOLEAN) {
356 return Boolean.toString(in.nextBoolean());
357 }
358 return in.nextString();
359 }
360 @Override
361 public void write(JsonWriter out, String value) throws IOException {
362 out.value(value);
363 }
364 };
365
366 public static final TypeAdapter<BigDecimal> BIG_DECIMAL = new TypeAdapter<BigDecimal>() {
367 @Override public BigDecimal read(JsonReader in) throws IOException {
368 if (in.peek() == JsonToken.NULL) {
369 in.nextNull();
370 return null;
371 }
372 try {
373 return new BigDecimal(in.nextString());
374 } catch (NumberFormatException e) {
375 throw new JsonSyntaxException(e);
376 }
377 }
378
379 @Override public void write(JsonWriter out, BigDecimal value) throws IOException {
380 out.value(value);
381 }
382 };
383
384 public static final TypeAdapter<BigInteger> BIG_INTEGER = new TypeAdapter<BigInteger>() {
385 @Override public BigInteger read(JsonReader in) throws IOException {
386 if (in.peek() == JsonToken.NULL) {
387 in.nextNull();
388 return null;
389 }
390 try {
391 return new BigInteger(in.nextString());
392 } catch (NumberFormatException e) {
393 throw new JsonSyntaxException(e);
394 }
395 }
396
397 @Override public void write(JsonWriter out, BigInteger value) throws IOException {
398 out.value(value);
399 }
400 };
401
402 public static final TypeAdapterFactory STRING_FACTORY = newFactory(String.class, STRING);
403
404 public static final TypeAdapter<StringBuilder> STRING_BUILDER = new TypeAdapter<StringBuilder>() {
405 @Override
406 public StringBuilder read(JsonReader in) throws IOException {
407 if (in.peek() == JsonToken.NULL) {
408 in.nextNull();
409 return null;
410 }
411 return new StringBuilder(in.nextString());
412 }
413 @Override
414 public void write(JsonWriter out, StringBuilder value) throws IOException {
415 out.value(value == null ? null : value.toString());
416 }
417 };
418
419 public static final TypeAdapterFactory STRING_BUILDER_FACTORY =
420 newFactory(StringBuilder.class, STRING_BUILDER);
421
422 public static final TypeAdapter<StringBuffer> STRING_BUFFER = new TypeAdapter<StringBuffer>() {
423 @Override
424 public StringBuffer read(JsonReader in) throws IOException {
425 if (in.peek() == JsonToken.NULL) {
426 in.nextNull();
427 return null;
428 }
429 return new StringBuffer(in.nextString());
430 }
431 @Override
432 public void write(JsonWriter out, StringBuffer value) throws IOException {
433 out.value(value == null ? null : value.toString());
434 }
435 };
436
437 public static final TypeAdapterFactory STRING_BUFFER_FACTORY =
438 newFactory(StringBuffer.class, STRING_BUFFER);
439
440 public static final TypeAdapter<URL> URL = new TypeAdapter<URL>() {
441 @Override
442 public URL read(JsonReader in) throws IOException {
443 if (in.peek() == JsonToken.NULL) {
444 in.nextNull();
445 return null;
446 }
447 String nextString = in.nextString();
448 return "null".equals(nextString) ? null : new URL(nextString);
449 }
450 @Override
451 public void write(JsonWriter out, URL value) throws IOException {
452 out.value(value == null ? null : value.toExternalForm());
453 }
454 };
455
456 public static final TypeAdapterFactory URL_FACTORY = newFactory(URL.class, URL);
457
458 public static final TypeAdapter<URI> URI = new TypeAdapter<URI>() {
459 @Override
460 public URI read(JsonReader in) throws IOException {
461 if (in.peek() == JsonToken.NULL) {
462 in.nextNull();
463 return null;
464 }
465 try {
466 String nextString = in.nextString();
467 return "null".equals(nextString) ? null : new URI(nextString);
468 } catch (URISyntaxException e) {
469 throw new JsonIOException(e);
470 }
471 }
472 @Override
473 public void write(JsonWriter out, URI value) throws IOException {
474 out.value(value == null ? null : value.toASCIIString());
475 }
476 };
477
478 public static final TypeAdapterFactory URI_FACTORY = newFactory(URI.class, URI);
479
480 public static final TypeAdapter<InetAddress> INET_ADDRESS = new TypeAdapter<InetAddress>() {
481 @Override
482 public InetAddress read(JsonReader in) throws IOException {
483 if (in.peek() == JsonToken.NULL) {
484 in.nextNull();
485 return null;
486 }
487 // regrettably, this should have included both the host name and the host address
488 return InetAddress.getByName(in.nextString());
489 }
490 @Override
491 public void write(JsonWriter out, InetAddress value) throws IOException {
492 out.value(value == null ? null : value.getHostAddress());
493 }
494 };
495
496 public static final TypeAdapterFactory INET_ADDRESS_FACTORY =
497 newTypeHierarchyFactory(InetAddress.class, INET_ADDRESS);
498
499 public static final TypeAdapter<UUID> UUID = new TypeAdapter<UUID>() {
500 @Override
501 public UUID read(JsonReader in) throws IOException {
502 if (in.peek() == JsonToken.NULL) {
503 in.nextNull();
504 return null;
505 }
506 return java.util.UUID.fromString(in.nextString());
507 }
508 @Override
509 public void write(JsonWriter out, UUID value) throws IOException {
510 out.value(value == null ? null : value.toString());
511 }
512 };
513
514 public static final TypeAdapterFactory UUID_FACTORY = newFactory(UUID.class, UUID);
515
516 public static final TypeAdapterFactory TIMESTAMP_FACTORY = new TypeAdapterFactory() {
517 @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
518 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
519 if (typeToken.getRawType() != Timestamp.class) {
520 return null;
521 }
522
523 final TypeAdapter<Date> dateTypeAdapter = gson.getAdapter(Date.class);
524 return (TypeAdapter<T>) new TypeAdapter<Timestamp>() {
525 @Override public Timestamp read(JsonReader in) throws IOException {
526 Date date = dateTypeAdapter.read(in);
527 return date != null ? new Timestamp(date.getTime()) : null;
528 }
529
530 @Override public void write(JsonWriter out, Timestamp value) throws IOException {
531 dateTypeAdapter.write(out, value);
532 }
533 };
534 }
535 };
536
537 public static final TypeAdapter<Calendar> CALENDAR = new TypeAdapter<Calendar>() {
538 private static final String YEAR = "year";
539 private static final String MONTH = "month";
540 private static final String DAY_OF_MONTH = "dayOfMonth";
541 private static final String HOUR_OF_DAY = "hourOfDay";
542 private static final String MINUTE = "minute";
543 private static final String SECOND = "second";
544
545 @Override
546 public Calendar read(JsonReader in) throws IOException {
547 if (in.peek() == JsonToken.NULL) {
548 in.nextNull();
549 return null;
550 }
551 in.beginObject();
552 int year = 0;
553 int month = 0;
554 int dayOfMonth = 0;
555 int hourOfDay = 0;
556 int minute = 0;
557 int second = 0;
558 while (in.peek() != JsonToken.END_OBJECT) {
559 String name = in.nextName();
560 int value = in.nextInt();
561 if (YEAR.equals(name)) {
562 year = value;
563 } else if (MONTH.equals(name)) {
564 month = value;
565 } else if (DAY_OF_MONTH.equals(name)) {
566 dayOfMonth = value;
567 } else if (HOUR_OF_DAY.equals(name)) {
568 hourOfDay = value;
569 } else if (MINUTE.equals(name)) {
570 minute = value;
571 } else if (SECOND.equals(name)) {
572 second = value;
573 }
574 }
575 in.endObject();
576 return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
577 }
578
579 @Override
580 public void write(JsonWriter out, Calendar value) throws IOException {
581 if (value == null) {
582 out.nullValue();
583 return;
584 }
585 out.beginObject();
586 out.name(YEAR);
587 out.value(value.get(Calendar.YEAR));
588 out.name(MONTH);
589 out.value(value.get(Calendar.MONTH));
590 out.name(DAY_OF_MONTH);
591 out.value(value.get(Calendar.DAY_OF_MONTH));
592 out.name(HOUR_OF_DAY);
593 out.value(value.get(Calendar.HOUR_OF_DAY));
594 out.name(MINUTE);
595 out.value(value.get(Calendar.MINUTE));
596 out.name(SECOND);
597 out.value(value.get(Calendar.SECOND));
598 out.endObject();
599 }
600 };
601
602 public static final TypeAdapterFactory CALENDAR_FACTORY =
603 newFactoryForMultipleTypes(Calendar.class, GregorianCalendar.class, CALENDAR);
604
605 public static final TypeAdapter<Locale> LOCALE = new TypeAdapter<Locale>() {
606 @Override
607 public Locale read(JsonReader in) throws IOException {
608 if (in.peek() == JsonToken.NULL) {
609 in.nextNull();
610 return null;
611 }
612 String locale = in.nextString();
613 StringTokenizer tokenizer = new StringTokenizer(locale, "_");
614 String language = null;
615 String country = null;
616 String variant = null;
617 if (tokenizer.hasMoreElements()) {
618 language = tokenizer.nextToken();
619 }
620 if (tokenizer.hasMoreElements()) {
621 country = tokenizer.nextToken();
622 }
623 if (tokenizer.hasMoreElements()) {
624 variant = tokenizer.nextToken();
625 }
626 if (country == null && variant == null) {
627 return new Locale(language);
628 } else if (variant == null) {
629 return new Locale(language, country);
630 } else {
631 return new Locale(language, country, variant);
632 }
633 }
634 @Override
635 public void write(JsonWriter out, Locale value) throws IOException {
636 out.value(value == null ? null : value.toString());
637 }
638 };
639
640 public static final TypeAdapterFactory LOCALE_FACTORY = newFactory(Locale.class, LOCALE);
641
642 public static final TypeAdapter<JsonElement> JSON_ELEMENT = new TypeAdapter<JsonElement>() {
643 @Override public JsonElement read(JsonReader in) throws IOException {
644 switch (in.peek()) {
645 case STRING:
646 return new JsonPrimitive(in.nextString());
647 case NUMBER:
648 String number = in.nextString();
649 return new JsonPrimitive(new LazilyParsedNumber(number));
650 case BOOLEAN:
651 return new JsonPrimitive(in.nextBoolean());
652 case NULL:
653 in.nextNull();
654 return JsonNull.INSTANCE;
655 case BEGIN_ARRAY:
656 JsonArray array = new JsonArray();
657 in.beginArray();
658 while (in.hasNext()) {
659 array.add(read(in));
660 }
661 in.endArray();
662 return array;
663 case BEGIN_OBJECT:
664 JsonObject object = new JsonObject();
665 in.beginObject();
666 while (in.hasNext()) {
667 object.add(in.nextName(), read(in));
668 }
669 in.endObject();
670 return object;
671 case END_DOCUMENT:
672 case NAME:
673 case END_OBJECT:
674 case END_ARRAY:
675 default:
676 throw new IllegalArgumentException();
677 }
678 }
679
680 @Override public void write(JsonWriter out, JsonElement value) throws IOException {
681 if (value == null || value.isJsonNull()) {
682 out.nullValue();
683 } else if (value.isJsonPrimitive()) {
684 JsonPrimitive primitive = value.getAsJsonPrimitive();
685 if (primitive.isNumber()) {
686 out.value(primitive.getAsNumber());
687 } else if (primitive.isBoolean()) {
688 out.value(primitive.getAsBoolean());
689 } else {
690 out.value(primitive.getAsString());
691 }
692
693 } else if (value.isJsonArray()) {
694 out.beginArray();
695 for (JsonElement e : value.getAsJsonArray()) {
696 write(out, e);
697 }
698 out.endArray();
699
700 } else if (value.isJsonObject()) {
701 out.beginObject();
702 for (Map.Entry<String, JsonElement> e : value.getAsJsonObject().entrySet()) {
703 out.name(e.getKey());
704 write(out, e.getValue());
705 }
706 out.endObject();
707
708 } else {
709 throw new IllegalArgumentException("Couldn't write " + value.getClass());
710 }
711 }
712 };
713
714 public static final TypeAdapterFactory JSON_ELEMENT_FACTORY
715 = newTypeHierarchyFactory(JsonElement.class, JSON_ELEMENT);
716
717 private static final class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
718 private final Map<String, T> nameToConstant = new HashMap<String, T>();
719 private final Map<T, String> constantToName = new HashMap<T, String>();
720
721 public EnumTypeAdapter(Class<T> classOfT) {
722 try {
723 for (T constant : classOfT.getEnumConstants()) {
724 String name = constant.name();
725 SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class);
726 if (annotation != null) {
727 name = annotation.value();
728 }
729 nameToConstant.put(name, constant);
730 constantToName.put(constant, name);
731 }
732 } catch (NoSuchFieldException e) {
733 throw new AssertionError();
734 }
735 }
736 public T read(JsonReader in) throws IOException {
737 if (in.peek() == JsonToken.NULL) {
738 in.nextNull();
739 return null;
740 }
741 return nameToConstant.get(in.nextString());
742 }
743
744 public void write(JsonWriter out, T value) throws IOException {
745 out.value(value == null ? null : constantToName.get(value));
746 }
747 }
748
749 public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory();
750
751 public static TypeAdapterFactory newEnumTypeHierarchyFactory() {
752 return new TypeAdapterFactory() {
753 @SuppressWarnings({"rawtypes", "unchecked"})
754 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
755 Class<? super T> rawType = typeToken.getRawType();
756 if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) {
757 return null;
758 }
759 if (!rawType.isEnum()) {
760 rawType = rawType.getSuperclass(); // handle anonymous subclasses
761 }
762 return (TypeAdapter<T>) new EnumTypeAdapter(rawType);
763 }
764 };
765 }
766
767 public static <TT> TypeAdapterFactory newFactory(
768 final TypeToken<TT> type, final TypeAdapter<TT> typeAdapter) {
769 return new TypeAdapterFactory() {
770 @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
771 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
772 return typeToken.equals(type) ? (TypeAdapter<T>) typeAdapter : null;
773 }
774 };
775 }
776
777 public static <TT> TypeAdapterFactory newFactory(
778 final Class<TT> type, final TypeAdapter<TT> typeAdapter) {
779 return new TypeAdapterFactory() {
780 @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
781 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
782 return typeToken.getRawType() == type ? (TypeAdapter<T>) typeAdapter : null;
783 }
784 @Override public String toString() {
785 return "Factory[type=" + type.getName() + ",adapter=" + typeAdapter + "]";
786 }
787 };
788 }
789
790 public static <TT> TypeAdapterFactory newFactory(
791 final Class<TT> unboxed, final Class<TT> boxed, final TypeAdapter<? super TT> typeAdapter) {
792 return new TypeAdapterFactory() {
793 @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
794 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
795 Class<? super T> rawType = typeToken.getRawType();
796 return (rawType == unboxed || rawType == boxed) ? (TypeAdapter<T>) typeAdapter : null;
797 }
798 @Override public String toString() {
799 return "Factory[type=" + boxed.getName()
800 + "+" + unboxed.getName() + ",adapter=" + typeAdapter + "]";
801 }
802 };
803 }
804
805 public static <TT> TypeAdapterFactory newFactoryForMultipleTypes(final Class<TT> base,
806 final Class<? extends TT> sub, final TypeAdapter<? super TT> typeAdapter) {
807 return new TypeAdapterFactory() {
808 @SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
809 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
810 Class<? super T> rawType = typeToken.getRawType();
811 return (rawType == base || rawType == sub) ? (TypeAdapter<T>) typeAdapter : null;
812 }
813 @Override public String toString() {
814 return "Factory[type=" + base.getName()
815 + "+" + sub.getName() + ",adapter=" + typeAdapter + "]";
816 }
817 };
818 }
819
820 public static <TT> TypeAdapterFactory newTypeHierarchyFactory(
821 final Class<TT> clazz, final TypeAdapter<TT> typeAdapter) {
822 return new TypeAdapterFactory() {
823 @SuppressWarnings("unchecked")
824 public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
825 return clazz.isAssignableFrom(typeToken.getRawType()) ? (TypeAdapter<T>) typeAdapter : null;
826 }
827 @Override public String toString() {
828 return "Factory[typeHierarchy=" + clazz.getName() + ",adapter=" + typeAdapter + "]";
829 }
830 };
831 }
832 }
This page took 0.05037 seconds and 4 git commands to generate.