package com.fasterxml.jackson.databind.objectid;
import java.net.URI;
import java.util.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
public class TestObjectIdWithEquals extends BaseMapTest
{
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Foo.class)
static class Foo {
public int id;
public List<Bar> bars = new ArrayList<Bar>();
public List<Bar> otherBars = new ArrayList<Bar>();
public Foo() { }
public Foo(int i) { id = i; }
}
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id", scope=Bar.class)
static class Bar
{
public int id;
public Bar() { }
public Bar(int i) {
id = i;
}
@Override
public int hashCode() {
return id;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Bar)) {
return false;
}
return ((Bar) obj).id == id;
}
}
// for [databind#1002]
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "uri")
static class Element {
public URI uri;
public String name;
@Override
public boolean equals(Object object) {
if (object == this) {
return true;
} else if (object == null || !(object instanceof Element)) {
return false;
} else {
Element element = (Element) object;
if (element.uri.toString().equalsIgnoreCase(this.uri.toString())) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return uri.hashCode();
}
}
/*
/******************************************************
/* Test methods
/******************************************************
*/
public void testSimpleEquals() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
// Verify default state too
assertFalse(mapper.isEnabled(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID));
mapper.enable(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID);
Foo foo = new Foo(1);
Bar bar1 = new Bar(1);
Bar bar2 = new Bar(2);
// this is another bar which is supposed to be "equal" to bar1
// due to the same ID and
// Bar class' equals() method will return true.
Bar anotherBar1 = new Bar(1);
foo.bars.add(bar1);
foo.bars.add(bar2);
// this anotherBar1 object will confuse the serializer.
foo.otherBars.add(anotherBar1);
foo.otherBars.add(bar2);
String json = mapper.writeValueAsString(foo);
assertEquals("{\"id\":1,\"bars\":[{\"id\":1},{\"id\":2}],\"otherBars\":[1,2]}", json);
Foo foo2 = mapper.readValue(json, Foo.class);
assertNotNull(foo2);
assertEquals(foo.id, foo2.id);
}
public void testEqualObjectIdsExternal() throws Exception
{
Element element = new Element();
element.uri = URI.create("URI");
element.name = "Element1";
Element element2 = new Element();
element2.uri = URI.create("URI");
element2.name = "Element2";
// 12-Nov-2015, tatu: array works fine regardless of Type Erasure, but if using List,
// must provide additional piece of type info
// Element[] input = new Element[] { element, element2 };
List<Element> input = Arrays.asList(element, element2);
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID);
// String json = mapper.writeValueAsString(input);
String json = mapper.writerFor(new TypeReference<List<Element>>() { })
.writeValueAsString(input);
Element[] output = mapper.readValue(json, Element[].class);
assertNotNull(output);
assertEquals(2, output.length);
}
}