/*
* Copyright 2014 Nicolas Morel
*
* 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 com.github.nmorel.gwtjackson.shared.advanced;
import java.util.Arrays;
import java.util.List;
import java.util.TreeMap;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
import com.github.nmorel.gwtjackson.shared.AbstractTester;
import com.github.nmorel.gwtjackson.shared.ObjectReaderTester;
import com.github.nmorel.gwtjackson.shared.ObjectWriterTester;
import com.google.gwt.core.client.GWT;
/**
* @author Nicolas Morel
*/
public final class WildcardTester extends AbstractTester {
@JsonTypeInfo( use = Id.NAME, include = As.PROPERTY, property = "type" )
@JsonSubTypes( {@Type( value = Dog.class, name = "doggy" ), @Type( value = Cat.class, name = "cat" )} )
public static abstract class Animal {
public String name;
}
public static class Dog extends Animal {
public int boneCount;
@JsonCreator
public Dog( @JsonProperty( "name" ) String name, @JsonProperty( "boneCount" ) int b ) {
super();
this.name = name;
boneCount = b;
}
}
public static class Cat extends Animal {
@JsonCreator
public Cat( @JsonProperty( "name" ) String name ) {
super();
this.name = name;
}
}
public static class SimpleWildcard {
private List<? extends Animal> animals;
private SimpleWildcard() {}
public List<? extends Animal> getAnimals() {
return animals;
}
public void setAnimals( List<? extends Animal> animals ) {
this.animals = animals;
}
}
public static class AnimalWildcard<T extends Animal> {
private List<T> animals;
private AnimalWildcard() {}
public List<T> getAnimals() {
return animals;
}
public void setAnimals( List<T> animals ) {
this.animals = animals;
}
}
public static class GenericWildcard<T> {
private List<? extends T> generics;
private GenericWildcard() {}
public List<? extends T> getGenerics() {
return generics;
}
public void setGenerics( List<? extends T> generics ) {
this.generics = generics;
}
}
@JsonTypeInfo( use = Id.NAME, include = As.PROPERTY, property = "type" )
@JsonSubTypes( {@Type( value = EnumString.class, name = "string" )} )
public static abstract class AbstractEnum<T extends Comparable<T>> {
private TreeMap<T, String> map = new TreeMap<T, String>();
public TreeMap<T, String> getMap() {
return map;
}
public void setMap( TreeMap<T, String> map ) {
this.map = map;
}
}
public static class EnumString extends AbstractEnum<String> {
}
public static class BeanWithCustomEnumMap<T extends Comparable<T>> {
private AbstractEnum<T> enumMap;
public AbstractEnum<T> getEnumMap() {
return enumMap;
}
public void setEnumMap( AbstractEnum<T> enumMap ) {
this.enumMap = enumMap;
}
}
public static final WildcardTester INSTANCE = new WildcardTester();
private WildcardTester() {
}
public void testSerializeSimpleWildcard( ObjectWriterTester<SimpleWildcard> writer ) {
SimpleWildcard bean = new SimpleWildcard();
bean.animals = Arrays.asList( new Dog( "Bully", 120 ), new Cat( "Felix" ) );
String expected = "{\"animals\":[" +
"{" +
"\"type\":\"doggy\"," +
"\"name\":\"Bully\"," +
"\"boneCount\":120" +
"}," +
"{" +
"\"type\":\"cat\"," +
"\"name\":\"Felix\"" +
"}" +
"]}";
assertEquals( expected, writer.write( bean ) );
}
public void testDeserializeSimpleWildcard( ObjectReaderTester<SimpleWildcard> reader ) {
String input = "{\"animals\":[" +
"{" +
"\"type\":\"doggy\"," +
"\"name\":\"Bully\"," +
"\"boneCount\":120" +
"}," +
"{" +
"\"type\":\"cat\"," +
"\"name\":\"Felix\"" +
"}" +
"]}";
SimpleWildcard bean = reader.read( input );
assertNotNull( bean );
assertEquals( 2, bean.animals.size() );
assertTrue( bean.animals.get( 0 ) instanceof Dog );
Dog dog = (Dog) bean.animals.get( 0 );
assertEquals( "Bully", dog.name );
assertEquals( 120, dog.boneCount );
assertTrue( bean.animals.get( 1 ) instanceof Cat );
Cat cat = (Cat) bean.animals.get( 1 );
assertEquals( "Felix", cat.name );
}
public void testSerializeAnimalWildcard( ObjectWriterTester<AnimalWildcard> writer ) {
AnimalWildcard bean = new AnimalWildcard();
bean.animals = Arrays.asList( new Dog( "Bully", 120 ), new Cat( "Felix" ) );
String expected = "{\"animals\":[" +
"{" +
"\"type\":\"doggy\"," +
"\"name\":\"Bully\"," +
"\"boneCount\":120" +
"}," +
"{" +
"\"type\":\"cat\"," +
"\"name\":\"Felix\"" +
"}" +
"]}";
assertEquals( expected, writer.write( bean ) );
}
public void testDeserializeAnimalWildcard( ObjectReaderTester<AnimalWildcard> reader ) {
String input = "{\"animals\":[" +
"{" +
"\"type\":\"doggy\"," +
"\"name\":\"Bully\"," +
"\"boneCount\":120" +
"}," +
"{" +
"\"type\":\"cat\"," +
"\"name\":\"Felix\"" +
"}" +
"]}";
AnimalWildcard bean = reader.read( input );
assertNotNull( bean );
assertEquals( 2, bean.animals.size() );
assertTrue( bean.animals.get( 0 ) instanceof Dog );
Dog dog = (Dog) bean.animals.get( 0 );
assertEquals( "Bully", dog.name );
assertEquals( 120, dog.boneCount );
assertTrue( bean.animals.get( 1 ) instanceof Cat );
Cat cat = (Cat) bean.animals.get( 1 );
assertEquals( "Felix", cat.name );
}
public void testSerializeGenericWildcard( ObjectWriterTester<GenericWildcard<Animal>> writer ) {
GenericWildcard<Animal> bean = new GenericWildcard<Animal>();
bean.generics = Arrays.asList( new Dog( "Bully", 120 ), new Cat( "Felix" ) );
String expected;
if ( GWT.isClient() ) {
expected = "{\"generics\":[" +
"{" +
"\"type\":\"doggy\"," +
"\"name\":\"Bully\"," +
"\"boneCount\":120" +
"}," +
"{" +
"\"type\":\"cat\"," +
"\"name\":\"Felix\"" +
"}" +
"]}";
} else {
expected = "{\"generics\":[" +
"{" +
"\"name\":\"Bully\"," +
"\"boneCount\":120" +
"}," +
"{" +
"\"name\":\"Felix\"" +
"}" +
"]}";
}
assertEquals( expected, writer.write( bean ) );
}
public void testDeserializeGenericWildcard( ObjectReaderTester<GenericWildcard<Animal>> reader ) {
String input = "{\"generics\":[" +
"{" +
"\"type\":\"doggy\"," +
"\"name\":\"Bully\"," +
"\"boneCount\":120" +
"}," +
"{" +
"\"type\":\"cat\"," +
"\"name\":\"Felix\"" +
"}" +
"]}";
GenericWildcard<Animal> bean = reader.read( input );
assertNotNull( bean );
assertEquals( 2, bean.generics.size() );
assertTrue( bean.generics.get( 0 ) instanceof Dog );
Dog dog = (Dog) bean.generics.get( 0 );
assertEquals( "Bully", dog.name );
assertEquals( 120, dog.boneCount );
assertTrue( bean.generics.get( 1 ) instanceof Cat );
Cat cat = (Cat) bean.generics.get( 1 );
assertEquals( "Felix", cat.name );
}
public void testSerializeBeanWithCustomEnumMap( ObjectWriterTester<BeanWithCustomEnumMap<String>> writer ) {
BeanWithCustomEnumMap<String> bean = new BeanWithCustomEnumMap<String>();
EnumString enums = new EnumString();
enums.getMap().put( "Hello", "World" );
bean.setEnumMap( enums );
String expected = "{\"enumMap\":{\"type\":\"string\",\"map\":{\"Hello\":\"World\"}}}";
assertEquals( expected, writer.write( bean ) );
}
public void testDeserializeBeanWithCustomEnumMap( ObjectReaderTester<BeanWithCustomEnumMap<String>> reader ) {
String input = "{\"enumMap\":{\"type\":\"string\",\"map\":{\"Hello\":\"World\"}}}";
BeanWithCustomEnumMap bean = reader.read( input );
assertNotNull( bean );
assertEquals( 1, bean.getEnumMap().getMap().size() );
assertEquals( "World", bean.getEnumMap().getMap().get( "Hello" ) );
}
}