• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.functional;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertTrue;
21 
22 import com.google.gson.Gson;
23 import com.google.gson.GsonBuilder;
24 import com.google.gson.JsonDeserializationContext;
25 import com.google.gson.JsonDeserializer;
26 import com.google.gson.JsonElement;
27 import com.google.gson.JsonParseException;
28 import com.google.gson.JsonPrimitive;
29 import com.google.gson.JsonSerializationContext;
30 import com.google.gson.JsonSerializer;
31 import com.google.gson.reflect.TypeToken;
32 import java.lang.reflect.ParameterizedType;
33 import java.lang.reflect.Type;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.List;
37 import org.junit.Before;
38 import org.junit.Test;
39 
40 /**
41  * Collection of functional tests for DOM tree based type adapters.
42  */
43 public class TreeTypeAdaptersTest {
44   private static final Id<Student> STUDENT1_ID = new Id<>("5", Student.class);
45   private static final Id<Student> STUDENT2_ID = new Id<>("6", Student.class);
46   private static final Student STUDENT1 = new Student(STUDENT1_ID, "first");
47   private static final Student STUDENT2 = new Student(STUDENT2_ID, "second");
48   private static final Type TYPE_COURSE_HISTORY =
49     new TypeToken<Course<HistoryCourse>>(){}.getType();
50   private static final Id<Course<HistoryCourse>> COURSE_ID =
51       new Id<>("10", TYPE_COURSE_HISTORY);
52 
53   private Gson gson;
54   private Course<HistoryCourse> course;
55 
56   @Before
setUp()57   public void setUp() {
58     gson = new GsonBuilder()
59         .registerTypeAdapter(Id.class, new IdTreeTypeAdapter())
60         .create();
61     course = new Course<>(COURSE_ID, 4,
62         new Assignment<HistoryCourse>(null, null), Arrays.asList(STUDENT1, STUDENT2));
63   }
64 
65   @Test
testSerializeId()66   public void testSerializeId() {
67     String json = gson.toJson(course, TYPE_COURSE_HISTORY);
68     assertTrue(json.contains(String.valueOf(COURSE_ID.getValue())));
69     assertTrue(json.contains(String.valueOf(STUDENT1_ID.getValue())));
70     assertTrue(json.contains(String.valueOf(STUDENT2_ID.getValue())));
71   }
72 
73   @Test
testDeserializeId()74   public void testDeserializeId() {
75     String json = "{courseId:1,students:[{id:1,name:'first'},{id:6,name:'second'}],"
76       + "numAssignments:4,assignment:{}}";
77     Course<HistoryCourse> target = gson.fromJson(json, TYPE_COURSE_HISTORY);
78     assertEquals("1", target.getStudents().get(0).id.getValue());
79     assertEquals("6", target.getStudents().get(1).id.getValue());
80     assertEquals("1", target.getId().getValue());
81   }
82 
83   private static final class Id<R> {
84     final String value;
85     @SuppressWarnings("unused")
86     final Type typeOfId;
87 
Id(String value, Type typeOfId)88     private Id(String value, Type typeOfId) {
89       this.value = value;
90       this.typeOfId = typeOfId;
91     }
getValue()92     public String getValue() {
93       return value;
94     }
95   }
96 
97   private static final class IdTreeTypeAdapter implements JsonSerializer<Id<?>>,
98       JsonDeserializer<Id<?>> {
99 
100     @Override
deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)101     public Id<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
102         throws JsonParseException {
103       if (!(typeOfT instanceof ParameterizedType)) {
104         throw new JsonParseException("Id of unknown type: " + typeOfT);
105       }
106       ParameterizedType parameterizedType = (ParameterizedType) typeOfT;
107       // Since Id takes only one TypeVariable, the actual type corresponding to the first
108       // TypeVariable is the Type we are looking for
109       Type typeOfId = parameterizedType.getActualTypeArguments()[0];
110       return new Id<>(json.getAsString(), typeOfId);
111     }
112 
113     @Override
serialize(Id<?> src, Type typeOfSrc, JsonSerializationContext context)114     public JsonElement serialize(Id<?> src, Type typeOfSrc, JsonSerializationContext context) {
115       return new JsonPrimitive(src.getValue());
116     }
117   }
118 
119   @SuppressWarnings("unused")
120   private static class Student {
121     Id<Student> id;
122     String name;
123 
Student()124     private Student() {
125       this(null, null);
126     }
Student(Id<Student> id, String name)127     public Student(Id<Student> id, String name) {
128       this.id = id;
129       this.name = name;
130     }
131   }
132 
133   @SuppressWarnings("unused")
134   private static class Course<T> {
135     final List<Student> students;
136     private final Id<Course<T>> courseId;
137     private final int numAssignments;
138     private final Assignment<T> assignment;
139 
Course()140     private Course() {
141       this(null, 0, null, new ArrayList<Student>());
142     }
143 
Course(Id<Course<T>> courseId, int numAssignments, Assignment<T> assignment, List<Student> players)144     public Course(Id<Course<T>> courseId, int numAssignments,
145         Assignment<T> assignment, List<Student> players) {
146       this.courseId = courseId;
147       this.numAssignments = numAssignments;
148       this.assignment = assignment;
149       this.students = players;
150     }
getId()151     public Id<Course<T>> getId() {
152       return courseId;
153     }
getStudents()154     List<Student> getStudents() {
155       return students;
156     }
157   }
158 
159   @SuppressWarnings("unused")
160   private static class Assignment<T> {
161     private final Id<Assignment<T>> id;
162     private final T data;
163 
Assignment()164     private Assignment() {
165       this(null, null);
166     }
Assignment(Id<Assignment<T>> id, T data)167     public Assignment(Id<Assignment<T>> id, T data) {
168       this.id = id;
169       this.data = data;
170     }
171   }
172 
173   @SuppressWarnings("unused")
174   private static class HistoryCourse {
175     int numClasses;
176   }
177 }
178