/* * 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.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; 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; /** * Tester for serializing and deserializing {@link Object}. * * @author Nicolas Morel */ public final class ObjectTester extends AbstractTester { public static class ObjectWrapper { public Object array; public Object string; public Object decimal; public Object integer; public Object longNumber; public Object bool; public Object map; public Object object; @JsonTypeInfo( include = As.PROPERTY, use = Id.CLASS, property = "@type" ) public Object objectWithTypeInfo; public Map<Object, String> mapWithObjectKey; public List objects; @JsonTypeInfo( include = As.PROPERTY, use = Id.CLASS, property = "@type2" ) public List objectsWithTypeInfo; } // annotation will be ignored @JsonTypeInfo(include = As.PROPERTY, use = Id.CLASS, property = "@class") public static class InnerObject { public String myString; public int myInt; } public static class Person { private final String firstName; private final String lastName; public Person( String firstName, String lastName ) { this.firstName = firstName; this.lastName = lastName; } @Override public boolean equals( Object o ) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } Person person = (Person) o; if ( !firstName.equals( person.firstName ) ) { return false; } if ( !lastName.equals( person.lastName ) ) { return false; } return true; } @Override public int hashCode() { int result = firstName.hashCode(); result = 31 * result + lastName.hashCode(); return result; } @Override public String toString() { return firstName + " " + lastName; } } public static final ObjectTester INSTANCE = new ObjectTester(); private ObjectTester() { } public void testSerializeObject( ObjectWriterTester<ObjectWrapper> writer ) { ObjectWrapper wrapper = new ObjectWrapper(); wrapper.array = new ArrayList<String>( Arrays.asList( "Hello", "World", "!" ) ); wrapper.string = "Dumb"; wrapper.decimal = 0.0148787d; wrapper.integer = 154514; wrapper.longNumber = 1545147777777777777l; wrapper.bool = true; Map<String, Object> objectMap = new LinkedHashMap<String, Object>(); objectMap.put( "first", "Dumb" ); objectMap.put( "second", "and" ); objectMap.put( "third", "Dumber" ); wrapper.map = objectMap; InnerObject inner = new InnerObject(); inner.myString = "a super string"; inner.myInt = 168555; wrapper.object = inner; wrapper.objectWithTypeInfo = inner; Map<Object, String> mapWithObjectKey = new LinkedHashMap<Object, String>(); mapWithObjectKey.put( new Person( "Steve", "Rogers" ), "Captain America" ); mapWithObjectKey.put( new Person( "Anthony", "Stark" ), "Iron Man" ); mapWithObjectKey.put( "Thor", "Thor" ); mapWithObjectKey.put( new Person( "Peter", "Parker" ), "Spider-Man" ); wrapper.mapWithObjectKey = mapWithObjectKey; List objectsWithTypeInfo = new ArrayList(); objectsWithTypeInfo.add( new BigDecimal( "4878451.154545" ) ); objectsWithTypeInfo.add( inner ); objectsWithTypeInfo.add( new Date( 1345304756543l ) ); wrapper.objects = objectsWithTypeInfo; wrapper.objectsWithTypeInfo = objectsWithTypeInfo; String expected = "{" + "\"array\":[\"Hello\",\"World\",\"!\"]," + "\"string\":\"Dumb\"," + "\"decimal\":0.0148787," + "\"integer\":154514," + "\"longNumber\":1545147777777777777," + "\"bool\":true," + "\"map\":{\"first\":\"Dumb\",\"second\":\"and\",\"third\":\"Dumber\"}," + "\"object\":{\"myString\":\"a super string\",\"myInt\":168555}," + "\"objectWithTypeInfo\":{" + "\"@type\":\"com.github.nmorel.gwtjackson.shared.advanced.ObjectTester$InnerObject\"," + "\"myString\":\"a super string\"," + "\"myInt\":168555" + "}," + "\"mapWithObjectKey\":{" + "\"Steve Rogers\":\"Captain America\"," + "\"Anthony Stark\":\"Iron Man\"," + "\"Thor\":\"Thor\"," + "\"Peter Parker\":\"Spider-Man\"" + "}," + "\"objects\":[" + "4878451.154545," + "{\"myString\":\"a super string\",\"myInt\":168555}," + "1345304756543" + "]," + "\"objectsWithTypeInfo\":[" + "[\"java.math.BigDecimal\",4878451.154545]," + "{\"@type2\":\"com.github.nmorel.gwtjackson.shared.advanced.ObjectTester$InnerObject\",\"myString\":\"a super string\"," + "\"myInt\":168555}," + "[\"java.util.Date\",1345304756543]" + "]" + "}"; assertEquals( expected, writer.write( wrapper ) ); } public void testDeserializeObject( ObjectReaderTester<ObjectWrapper> reader ) { String input = "{" + "\"array\":[\"Hello\",\"World\",\"!\"]," + "\"string\":\"Dumb\"," + "\"decimal\":0.0148787," + "\"integer\":154514," + "\"longNumber\":1545147777777777777," + "\"bool\":true," + "\"map\":{\"first\":\"Dumb\",\"second\":\"and\",\"third\":\"Dumber\"}," + "\"object\":{\"myString\":\"a super string\",\"myInt\":168555}," + "\"objectWithTypeInfo\":{" + "\"@type\":\"com.github.nmorel.gwtjackson.shared.advanced.ObjectTester$InnerObject\"," + "\"myString\":\"a super string\"," + "\"myInt\":168555" + "}," + "\"mapWithObjectKey\":{" + "\"Steve Rogers\":\"Captain America\"," + "\"Anthony Stark\":\"Iron Man\"," + "\"Thor\":\"Thor\"," + "\"Peter Parker\":\"Spider-Man\"" + "}," + "\"objects\":[" + "4878451.154545," + "{\"myString\":\"a super string\",\"myInt\":168555}," + "1345304756543" + "]," + "\"objectsWithTypeInfo\":[" + "[\"java.math.BigDecimal\",4878451.154545]," + "{\"@type2\":\"com.github.nmorel.gwtjackson.shared.advanced.ObjectTester$InnerObject\",\"myString\":\"a super string\"," + "\"myInt\":168555}," + "[\"java.util.Date\",1345304756543]" + "]" + "}"; ObjectWrapper bean = reader.read( input ); assertNotNull( bean ); assertEquals( Arrays.asList( "Hello", "World", "!" ), bean.array ); assertEquals( "Dumb", bean.string ); assertEquals( new Double( 0.0148787d ), bean.decimal ); assertEquals( new Integer( 154514 ), bean.integer ); assertEquals( new Long( 1545147777777777777l ), bean.longNumber ); assertTrue( (Boolean) bean.bool ); Map<String, Object> map = (Map<String, Object>) bean.map; assertEquals( 3, map.size() ); assertEquals( "Dumb", map.get( "first" ) ); assertEquals( "and", map.get( "second" ) ); assertEquals( "Dumber", map.get( "third" ) ); Map<String, Object> object = (Map<String, Object>) bean.object; assertEquals( 2, object.size() ); assertEquals( "a super string", object.get( "myString" ) ); assertEquals( 168555, object.get( "myInt" ) ); InnerObject objectWithTypeInfo = (InnerObject) bean.objectWithTypeInfo; assertEquals( "a super string", objectWithTypeInfo.myString ); assertEquals( 168555, objectWithTypeInfo.myInt ); Map<Object, String> mapWithObjectKey = bean.mapWithObjectKey; assertEquals( 4, mapWithObjectKey.size() ); assertEquals( "Captain America", mapWithObjectKey.get( "Steve Rogers" ) ); assertEquals( "Iron Man", mapWithObjectKey.get( "Anthony Stark" ) ); assertEquals( "Thor", mapWithObjectKey.get( "Thor" ) ); assertEquals( "Spider-Man", mapWithObjectKey.get( "Peter Parker" ) ); List objects = bean.objects; assertEquals( 4878451.154545d, objects.get( 0 ) ); Map<String, Object> innerObject = (Map<String, Object>) objects.get( 1 ); assertEquals( "a super string", innerObject.get( "myString" ) ); assertEquals( 168555, innerObject.get( "myInt" ) ); assertEquals( 1345304756543l, objects.get( 2 ) ); List objectsWithTypeInfo = bean.objectsWithTypeInfo; assertEquals( new BigDecimal( "4878451.154545" ), objectsWithTypeInfo.get( 0 ) ); InnerObject innerObjectWithTypeInfo = (InnerObject) objectsWithTypeInfo.get( 1 ); assertEquals( "a super string", innerObjectWithTypeInfo.myString ); assertEquals( 168555, innerObjectWithTypeInfo.myInt ); assertEquals( new Date( 1345304756543l ), objectsWithTypeInfo.get( 2 ) ); } }