package com.owlike.genson.generics;
import com.owlike.genson.Genson;
import com.owlike.genson.GensonBuilder;
import com.owlike.genson.annotation.JsonProperty;
import com.owlike.genson.reflect.TypeUtil;
import org.junit.Test;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.*;
/**
* artifactId: genson
* <p/>
* version: 0.94 & 0.95
* Issue 4, Reported by jesper.hammarback
* http://code.google.com/p/genson/issues/detail?id=4
*/
public class GenericsCachingTest {
@Test
public void testTypeExpansionCaching() throws SecurityException, NoSuchFieldException {
Type typeOfFoosField = FooContainer.class.getDeclaredField("foos").getGenericType();
Type typeOfBarsField = BarContainer.class.getDeclaredField("bars").getGenericType();
Type typeOfDataField = FooBarContainer.class.getDeclaredField("data").getGenericType();
ParameterizedType expandedTypeOfFoosDataField = (ParameterizedType) TypeUtil.expandType(typeOfDataField,
typeOfFoosField);
ParameterizedType expandedTypeOfBarsDataField = (ParameterizedType) TypeUtil.expandType(typeOfDataField,
typeOfBarsField);
assertEquals(List.class, expandedTypeOfFoosDataField.getRawType());
assertEquals(Foo.class, expandedTypeOfFoosDataField.getActualTypeArguments()[0]);
// testing that those expanded types are considered as distinct in the cache
assertEquals(List.class, expandedTypeOfBarsDataField.getRawType());
assertEquals(Bar.class, expandedTypeOfBarsDataField.getActualTypeArguments()[0]);
}
@Test
public void testDistinctExpandedTypeNotMixed() throws Exception {
Genson genson = new GensonBuilder().setSkipNull(true).create();
FooContainer fooContainer = new FooContainer(new FooBarContainer<Foo>(Arrays.asList(new Foo("foo"))));
BarContainer barContainer = new BarContainer(new FooBarContainer<Bar>(Arrays.asList(new Bar("bar"))));
String fooContainerJson = genson.serialize(fooContainer);
String barContainerJson = genson.serialize(barContainer);
assertThat(fooContainerJson, is("{\"foos\":{\"data\":[{\"fooId\":\"foo\"}]}}"));
assertThat(barContainerJson, is("{\"bars\":{\"data\":[{\"barId\":\"bar\"}]}}"));
// lets also make sure deser works fine and types dont get mixed...
assertEquals(fooContainer, genson.deserialize(fooContainerJson, FooContainer.class));
assertEquals(barContainer, genson.deserialize(barContainerJson, BarContainer.class));
}
public static class FooContainer {
public final FooBarContainer<Foo> foos;
public FooContainer(@JsonProperty("foos") FooBarContainer<Foo> foos) {
this.foos = foos;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((foos == null) ? 0 : foos.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
FooContainer other = (FooContainer) obj;
if (foos == null) {
if (other.foos != null) return false;
} else if (!foos.equals(other.foos)) return false;
return true;
}
}
public static class BarContainer {
public final FooBarContainer<Bar> bars;
public BarContainer(@JsonProperty("bars") FooBarContainer<Bar> bars) {
this.bars = bars;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bars == null) ? 0 : bars.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
BarContainer other = (BarContainer) obj;
if (bars == null) {
if (other.bars != null) return false;
} else if (!bars.equals(other.bars)) return false;
return true;
}
}
public static class FooBarContainer<T> {
public final List<T> data;
public FooBarContainer(@JsonProperty("data") List<T> data) {
this.data = data;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((data == null) ? 0 : data.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
@SuppressWarnings("rawtypes") FooBarContainer other = (FooBarContainer) obj;
if (data == null) {
if (other.data != null) return false;
} else if (!data.equals(other.data)) return false;
return true;
}
}
public static class Foo {
public final String fooId;
public Foo(@JsonProperty("fooId") String fooId) {
this.fooId = fooId;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((fooId == null) ? 0 : fooId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Foo other = (Foo) obj;
if (fooId == null) {
if (other.fooId != null) return false;
} else if (!fooId.equals(other.fooId)) return false;
return true;
}
}
public static class Bar {
public final String barId;
public Bar(@JsonProperty("barId") String barId) {
this.barId = barId;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((barId == null) ? 0 : barId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Bar other = (Bar) obj;
if (barId == null) {
if (other.barId != null) return false;
} else if (!barId.equals(other.barId)) return false;
return true;
}
}
}