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