/json/src/test/java/io/airlift/json/TestJsonModule.java
Java | 389 lines | 308 code | 57 blank | 24 comment | 31 complexity | 99ed3bb063d89e590317cf5b14da3531 MD5 | raw file
- /*
- * Copyright 2010 Proofpoint, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package io.airlift.json;
- import com.fasterxml.jackson.annotation.JsonProperty;
- import com.fasterxml.jackson.core.JsonParser;
- import com.fasterxml.jackson.core.JsonToken;
- import com.fasterxml.jackson.core.type.TypeReference;
- import com.fasterxml.jackson.databind.DeserializationContext;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
- import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
- import com.google.common.base.Joiner;
- import com.google.common.base.Splitter;
- import com.google.common.collect.ImmutableList;
- import com.google.common.collect.ImmutableSet;
- import com.google.common.collect.Maps;
- import com.google.inject.Binder;
- import com.google.inject.Guice;
- import com.google.inject.Injector;
- import com.google.inject.Module;
- import org.joda.time.DateTime;
- import org.joda.time.format.ISODateTimeFormat;
- import org.testng.annotations.BeforeMethod;
- import org.testng.annotations.Test;
- import java.io.IOException;
- import java.util.List;
- import java.util.Map;
- import static com.google.common.base.MoreObjects.toStringHelper;
- import static io.airlift.json.JsonBinder.jsonBinder;
- import static org.joda.time.DateTimeZone.UTC;
- import static org.testng.Assert.assertEquals;
- public class TestJsonModule
- {
- public static final Car CAR = new Car()
- .setMake("BMW")
- .setModel("M3")
- .setYear(2011)
- .setPurchased(new DateTime().withZone(UTC))
- .setNotes("sweet!")
- .setNameList(superDuper("d*a*i*n"));
- private ObjectMapper objectMapper;
- @BeforeMethod
- public void setUp()
- throws Exception
- {
- Injector injector = Guice.createInjector(new JsonModule(),
- new Module()
- {
- @Override
- public void configure(Binder binder)
- {
- jsonBinder(binder).addSerializerBinding(SuperDuperNameList.class).toInstance(ToStringSerializer.instance);
- jsonBinder(binder).addDeserializerBinding(SuperDuperNameList.class).to(SuperDuperNameListDeserializer.class);
- }
- });
- objectMapper = injector.getInstance(ObjectMapper.class);
- }
- @Test
- public void testJsonCodecFactoryBinding()
- throws Exception
- {
- Injector injector = Guice.createInjector(new JsonModule());
- JsonCodecFactory codecFactory = injector.getInstance(JsonCodecFactory.class);
- Person.validatePersonJsonCodec(codecFactory.jsonCodec(Person.class));
- Person.validatePersonListJsonCodec(codecFactory.listJsonCodec(Person.class));
- Person.validatePersonMapJsonCodec(codecFactory.mapJsonCodec(String.class, Person.class));
- }
- @Test
- public void testSetup()
- throws Exception
- {
- assertEquals(CAR, CAR);
- String json = objectMapper.writeValueAsString(CAR);
- Car actual = objectMapper.readValue(json, Car.class);
- assertEquals(actual, CAR);
- }
- @Test
- public void testFieldDetection()
- throws Exception
- {
- Map<String, Object> actual = objectMapper.readValue(objectMapper.writeValueAsString(CAR), Map.class);
- // notes is not annotated so should not be included
- // color is null so should not be included
- assertEquals(actual.keySet(), ImmutableSet.of("make", "model", "year", "purchased", "nameList"));
- }
- @Test
- public void testDateTimeRendered()
- throws Exception
- {
- Map<String, Object> actual = objectMapper.readValue(objectMapper.writeValueAsString(CAR), Map.class);
- assertEquals(actual.get("purchased"), ISODateTimeFormat.dateTime().print(CAR.getPurchased()));
- }
- @Test
- public void testGuavaRoundTrip()
- throws Exception
- {
- ImmutableList<Integer> list = ImmutableList.of(3, 5, 8);
- String json = objectMapper.writeValueAsString(list);
- ImmutableList<Integer> actual = objectMapper.readValue(json, new TypeReference<ImmutableList<Integer>>() {});
- assertEquals(actual, list);
- }
- @Test
- public void testIgnoreUnknownFields()
- throws Exception
- {
- Map<String, Object> data = Maps.newHashMap(objectMapper.readValue(objectMapper.writeValueAsString(CAR), Map.class));
- // add an unknown field
- data.put("unknown", "bogus");
- // Jackson should deserialize the object correctly with the extra unknown data
- assertEquals(objectMapper.readValue(objectMapper.writeValueAsString(data), Car.class), CAR);
- }
- public static class Car
- {
- // These fields are public to make sure that Jackson is ignoring them
- public String make;
- public String model;
- public int year;
- public DateTime purchased;
- // property that will be null to verify that null fields are not rendered
- public String color;
- // non-json property to verify that auto-detection is disabled
- public String notes;
- // property that requires special serializer and deserializer
- public SuperDuperNameList nameList;
- @JsonProperty
- public String getMake()
- {
- return make;
- }
- @JsonProperty
- public Car setMake(String make)
- {
- this.make = make;
- return this;
- }
- @JsonProperty
- public String getModel()
- {
- return model;
- }
- @JsonProperty
- public Car setModel(String model)
- {
- this.model = model;
- return this;
- }
- @JsonProperty
- public int getYear()
- {
- return year;
- }
- @JsonProperty
- public Car setYear(int year)
- {
- this.year = year;
- return this;
- }
- @JsonProperty
- public DateTime getPurchased()
- {
- return purchased;
- }
- @JsonProperty
- public Car setPurchased(DateTime purchased)
- {
- this.purchased = purchased;
- return this;
- }
- @JsonProperty
- public String getColor()
- {
- return color;
- }
- @JsonProperty
- public Car setColor(String color)
- {
- this.color = color;
- return this;
- }
- @JsonProperty
- public SuperDuperNameList getNameList()
- {
- return nameList;
- }
- @JsonProperty
- public Car setNameList(SuperDuperNameList nameList)
- {
- this.nameList = nameList;
- return this;
- }
- // this field should not be written
- public String getNotes()
- {
- return notes;
- }
- public Car setNotes(String notes)
- {
- this.notes = notes;
- return this;
- }
- @Override
- public boolean equals(Object o)
- {
- if (this == o) {
- return true;
- }
- if (!(o instanceof Car)) {
- return false;
- }
- Car car = (Car) o;
- if (year != car.year) {
- return false;
- }
- if (color != null ? !color.equals(car.color) : car.color != null) {
- return false;
- }
- if (make != null ? !make.equals(car.make) : car.make != null) {
- return false;
- }
- if (model != null ? !model.equals(car.model) : car.model != null) {
- return false;
- }
- if (nameList != null ? !nameList.equals(car.nameList) : car.nameList != null) {
- return false;
- }
- if (purchased != null ? !purchased.equals(car.purchased) : car.purchased != null) {
- return false;
- }
- return true;
- }
- @Override
- public int hashCode()
- {
- int result = make != null ? make.hashCode() : 0;
- result = 31 * result + (model != null ? model.hashCode() : 0);
- result = 31 * result + year;
- result = 31 * result + (purchased != null ? purchased.hashCode() : 0);
- result = 31 * result + (color != null ? color.hashCode() : 0);
- result = 31 * result + (nameList != null ? nameList.hashCode() : 0);
- return result;
- }
- @Override
- public String toString()
- {
- return toStringHelper(this)
- .add("make", make)
- .add("model", model)
- .add("year", year)
- .add("purchased", purchased)
- .add("color", color)
- .add("notes", notes)
- .add("nameList", nameList)
- .toString();
- }
- }
- public static class SuperDuperNameList
- {
- private List<String> name;
- private SuperDuperNameList(String superDuperNameList)
- {
- this(superDuperNameList, null);
- }
- private SuperDuperNameList(String superDuperNameList, Object stopJacksonFromUsingStringConstructor)
- {
- this.name = ImmutableList.copyOf(Splitter.on('*').split(superDuperNameList));
- }
- public List<String> getName()
- {
- return name;
- }
- @Override
- public String toString()
- {
- return Joiner.on("*").join(name);
- }
- @Override
- public boolean equals(Object o)
- {
- if (this == o) {
- return true;
- }
- if (!(o instanceof SuperDuperNameList)) {
- return false;
- }
- SuperDuperNameList that = (SuperDuperNameList) o;
- if (!name.equals(that.name)) {
- return false;
- }
- return true;
- }
- @Override
- public int hashCode()
- {
- return name.hashCode();
- }
- }
- public final static class SuperDuperNameListDeserializer
- extends StdScalarDeserializer<SuperDuperNameList>
- {
- public SuperDuperNameListDeserializer()
- {
- super(SuperDuperNameList.class);
- }
- @Override
- public SuperDuperNameList deserialize(JsonParser jp, DeserializationContext context)
- throws IOException
- {
- JsonToken token = jp.getCurrentToken();
- if (token == JsonToken.VALUE_STRING) {
- return new SuperDuperNameList(jp.getText(), null);
- }
- throw context.mappingException(getValueClass());
- }
- }
- public static SuperDuperNameList superDuper(String superDuperNameList)
- {
- return new SuperDuperNameList(superDuperNameList, null);
- }
- }