/**
* GRANITE DATA SERVICES
* Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S.
*
* This file is part of the Granite Data Services Platform.
*
* Granite Data Services is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Granite Data Services is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA, or see <http://www.gnu.org/licenses/>.
*/
package org.granite.test.amf.convert;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.granite.messaging.amf.io.convert.Converter;
import org.granite.messaging.amf.io.convert.Converters;
import org.granite.messaging.amf.io.convert.Reverter;
import org.granite.messaging.amf.io.convert.impl.Array2Array;
import org.granite.messaging.amf.io.convert.impl.Array2Collection;
import org.granite.messaging.amf.io.convert.impl.Boolean2Boolean;
import org.granite.messaging.amf.io.convert.impl.Character2Character;
import org.granite.messaging.amf.io.convert.impl.Collection2Array;
import org.granite.messaging.amf.io.convert.impl.Collection2Collection;
import org.granite.messaging.amf.io.convert.impl.Compatibility;
import org.granite.messaging.amf.io.convert.impl.Date2Date;
import org.granite.messaging.amf.io.convert.impl.Map2Map;
import org.granite.messaging.amf.io.convert.impl.Number2BigDecimal;
import org.granite.messaging.amf.io.convert.impl.Number2BigInteger;
import org.granite.messaging.amf.io.convert.impl.Number2Byte;
import org.granite.messaging.amf.io.convert.impl.Number2Double;
import org.granite.messaging.amf.io.convert.impl.Number2Float;
import org.granite.messaging.amf.io.convert.impl.Number2Integer;
import org.granite.messaging.amf.io.convert.impl.Number2Long;
import org.granite.messaging.amf.io.convert.impl.Number2Short;
import org.granite.messaging.amf.io.convert.impl.String2Char;
import org.granite.messaging.amf.io.convert.impl.String2CharArray;
import org.granite.messaging.amf.io.convert.impl.String2Document;
import org.granite.messaging.amf.io.convert.impl.String2Locale;
import org.granite.messaging.amf.io.convert.impl.String2URI;
import org.granite.util.XMLUtil;
import org.granite.util.XMLUtilFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
/**
* @author Franck WOLFF
*/
@SuppressWarnings({ "unchecked", "unused", "boxing" })
public class TestDefaultConverters {
private Number[] arrayOfNumbers = new Number[] {
Byte.valueOf((byte)0),
Short.valueOf((short)0),
Integer.valueOf(0),
Long.valueOf(0L),
Float.valueOf((float)0.0),
Double.valueOf(0.0),
BigDecimal.valueOf(0.0),
BigDecimal.ZERO,
BigInteger.ZERO,
Byte.valueOf(Byte.MIN_VALUE),
Byte.valueOf(Byte.MAX_VALUE),
Short.valueOf(Short.MIN_VALUE),
Short.valueOf(Short.MAX_VALUE),
Integer.valueOf(Integer.MIN_VALUE),
Integer.valueOf(Integer.MAX_VALUE),
Long.valueOf(Long.MIN_VALUE),
Long.valueOf(Long.MAX_VALUE),
Float.valueOf(Float.MIN_VALUE),
Float.valueOf(Float.MAX_VALUE),
Double.valueOf(Double.MIN_VALUE),
Double.valueOf(Double.MAX_VALUE),
BigDecimal.valueOf(Double.MIN_VALUE),
BigDecimal.valueOf(Double.MAX_VALUE),
BigInteger.valueOf(Long.MIN_VALUE),
BigInteger.valueOf(Long.MAX_VALUE)
};
@SuppressWarnings("all")
private ArrayList<?> arrayListOfWildcard = new ArrayList();
private Field arrayListOfWildcardField = null;
@SuppressWarnings("all")
private HashMap<?, ?> hashMapOfWildcards = new HashMap();
private Field hashMapOfWildcardsField = null;
private Map<String, Integer> mapOfStringInteger = null;
private Field mapOfStringIntegerField = null;
private List<?> listOfWildcard = null;
private Field listOfWildcardField = null;
private Set<?> setOfWildcard = null;
private Field setOfWildcardField = null;
private char primitiveChar = '\0';
private Field primitiveCharField = null;
private char[] arrayOfChar = new char[] {'a', 'b', 'c'};
private Field arrayOfCharField = null;
private Character[] arrayOfCharacter = new Character[] {'a', 'b', 'c'};
private Field arrayOfCharacterField = null;
private Object[] arrayOfObjectString = new Object[]{"abc", null, "def", "", "ghi"};
private Object[] arrayOfObjectNumber = new Object[]{Integer.valueOf(45), null, Byte.valueOf((byte)12), BigDecimal.TEN, Double.valueOf(6.56)};
private Long[] arrayOfLong = new Long[]{Long.valueOf(45L), null, Long.valueOf(12L), Long.valueOf(10L), Long.valueOf(6L)};
private long[] arrayOfPrimitiveLong = new long[]{45L, 0L, 12L, 10L, 6L};
private List<Object> listOfObject = null;
private Field listOfObjectField = null;
private List<Set<String>> listOfSetOfString = null;
private Field listOfSetOfStringField = null;
private Set<Long> setOfLong = null;
private Field setOfLongField = null;
///////////////////////////////////////////////////////////////////////////
// Initialization
private Converters converters = null;
@Before
public void setUp() throws Exception {
try {
arrayListOfWildcardField = getClass().getDeclaredField("arrayListOfWildcard");
arrayListOfWildcardField.setAccessible(true);
hashMapOfWildcardsField = getClass().getDeclaredField("hashMapOfWildcards");
hashMapOfWildcardsField.setAccessible(true);
primitiveCharField = getClass().getDeclaredField("primitiveChar");
primitiveCharField.setAccessible(true);
arrayOfCharField = getClass().getDeclaredField("arrayOfChar");
arrayOfCharField.setAccessible(true);
arrayOfCharacterField = getClass().getDeclaredField("arrayOfCharacter");
arrayOfCharacterField.setAccessible(true);
listOfObjectField = getClass().getDeclaredField("listOfObject");
listOfObjectField.setAccessible(true);
listOfSetOfStringField = getClass().getDeclaredField("listOfSetOfString");
listOfSetOfStringField.setAccessible(true);
setOfLongField = getClass().getDeclaredField("setOfLong");
setOfLongField.setAccessible(true);
listOfWildcardField = getClass().getDeclaredField("listOfWildcard");
listOfWildcardField.setAccessible(true);
setOfWildcardField = getClass().getDeclaredField("setOfWildcard");
setOfWildcardField.setAccessible(true);
mapOfStringIntegerField = getClass().getDeclaredField("mapOfStringInteger");
mapOfStringIntegerField.setAccessible(true);
mapOfStringIntegerField = getClass().getDeclaredField("mapOfStringInteger");
mapOfStringIntegerField.setAccessible(true);
} catch (Exception e) {
fail("Coud not get fields: " + e.toString());
}
List<Class<? extends Converter>> converterClasses = new ArrayList<Class<? extends Converter>>();
converterClasses.add(Number2Integer.class);
converterClasses.add(Number2Long.class);
converterClasses.add(Number2Double.class);
converterClasses.add(Boolean2Boolean.class);
converterClasses.add(Collection2Collection.class);
converterClasses.add(Collection2Array.class);
converterClasses.add(Array2Array.class);
converterClasses.add(Array2Collection.class);
converterClasses.add(Date2Date.class);
converterClasses.add(Map2Map.class);
converterClasses.add(String2CharArray.class);
converterClasses.add(Number2BigDecimal.class);
converterClasses.add(Number2BigInteger.class);
converterClasses.add(Number2Byte.class);
converterClasses.add(Number2Float.class);
converterClasses.add(Number2Short.class);
converterClasses.add(String2Char.class);
converterClasses.add(String2Locale.class);
converterClasses.add(String2URI.class);
converterClasses.add(Character2Character.class);
converterClasses.add(Compatibility.class);
converterClasses.add(String2Document.class);
this.converters = new Converters(converterClasses);
}
@After
public void tearDown() throws Exception {
converters = null;
}
///////////////////////////////////////////////////////////////////////////
// Boolean2Boolean
@Test
public void testBoolean2Boolean() {
testBoolean2Boolean(Boolean.TRUE, Boolean.class);
testBoolean2Boolean(Boolean.FALSE, Boolean.class);
testBoolean2Boolean(null, Boolean.class);
testBoolean2Boolean(Boolean.TRUE, Boolean.TYPE);
testBoolean2Boolean(Boolean.FALSE, Boolean.TYPE);
testBoolean2Boolean(null, Boolean.TYPE);
Converter converter = new Boolean2Boolean(converters);
assertTrue(converter.canConvert(null, Boolean.class));
assertEquals(null, converter.convert(null, Boolean.class));
assertTrue(converter.canConvert(Boolean.TRUE, Boolean.class));
assertEquals(Boolean.TRUE, converter.convert(Boolean.TRUE, Boolean.class));
assertTrue(converter.canConvert(Boolean.FALSE, Boolean.class));
assertEquals(Boolean.FALSE, converter.convert(Boolean.FALSE, Boolean.class));
assertTrue(converter.canConvert(null, Boolean.TYPE));
assertEquals(Boolean.FALSE, converter.convert(null, Boolean.TYPE));
assertTrue(converter.canConvert(Boolean.TRUE, Boolean.TYPE));
assertEquals(Boolean.TRUE, converter.convert(Boolean.TRUE, Boolean.TYPE));
assertTrue(converter.canConvert(Boolean.FALSE, Boolean.class));
assertEquals(Boolean.FALSE, converter.convert(Boolean.FALSE, Boolean.TYPE));
}
private void testBoolean2Boolean(Object value, Type targetType) {
Converter converter = converters.getConverter(value, targetType);
assertNotNull(converter);
assertEquals(Boolean2Boolean.class, converter.getClass());
assertTrue(converter.canConvert(value, targetType));
if (targetType == Boolean.class || value != null)
assertEquals(value, converter.convert(value, targetType));
else
assertEquals(Boolean.FALSE, converter.convert(value, targetType));
}
///////////////////////////////////////////////////////////////////////////
// Number2<Number>
@Test
public void testNumber2Number() {
testNumber2Number(new Number2Byte(converters), Byte.class, Byte.TYPE, new DirectConverter() {
public Object convert(Object o) {
return o instanceof Byte ? o : Byte.valueOf(((Number)o).byteValue());
}
});
testNumber2Number(new Number2Short(converters), Short.class, Short.TYPE, new DirectConverter() {
public Object convert(Object o) {
return o instanceof Short ? o : Short.valueOf(((Number)o).shortValue());
}
});
testNumber2Number(new Number2Integer(converters), Integer.class, Integer.TYPE, new DirectConverter() {
public Object convert(Object o) {
return o instanceof Integer ? o : Integer.valueOf(((Number)o).intValue());
}
});
testNumber2Number(new Number2Long(converters), Long.class, Long.TYPE, new DirectConverter() {
public Object convert(Object o) {
return o instanceof Long ? o : Long.valueOf(((Number)o).longValue());
}
});
testNumber2Number(new Number2Float(converters), Float.class, Float.TYPE, new DirectConverter() {
public Object convert(Object o) {
return o instanceof Float ? o : Float.valueOf(((Number)o).floatValue());
}
});
testNumber2Number(new Number2Double(converters), Double.class, Double.TYPE, new DirectConverter() {
public Object convert(Object o) {
return o instanceof Double ? o : Double.valueOf(((Number)o).doubleValue());
}
});
testNumber2Number(new Number2BigDecimal(converters), BigDecimal.class, null, new DirectConverter() {
public Object convert(Object o) {
return o instanceof BigDecimal ? o : BigDecimal.valueOf(((Number)o).doubleValue());
}
});
testNumber2Number(new Number2BigInteger(converters), BigInteger.class, null, new DirectConverter() {
public Object convert(Object o) {
return o instanceof BigInteger ? o : BigInteger.valueOf(((Number)o).longValue());
}
});
}
private void testNumber2Number(Converter numberConverter, Type targetType, Type targetPrimitiveType, DirectConverter directConverter) {
// Test for various numbers.
for (Number number : arrayOfNumbers) {
Converter converter = converters.getConverter(number, targetType);
assertNotNull(converter);
assertEquals(numberConverter.getClass(), converter.getClass());
assertTrue(converter.canConvert(number, targetType));
Object result = converter.convert(number, targetType);
assertEquals(targetType, result.getClass());
assertEquals(directConverter.convert(number), result);
}
// Test for null (with primitive conversion if any).
assertTrue(numberConverter.canConvert(null, targetType));
assertEquals(null, numberConverter.convert(null, targetType));
if (targetPrimitiveType != null) {
assertTrue(numberConverter.canConvert(null, targetPrimitiveType));
Object result = numberConverter.convert(null, targetPrimitiveType);
assertEquals(targetType, result.getClass());
assertEquals(directConverter.convert(Integer.valueOf(0)), result);
}
}
///////////////////////////////////////////////////////////////////////////
// String2Char
@Test
public void testString2Char() {
Converter converter = converters.getConverter("a", Character.class);
assertNotNull(converter);
assertEquals(String2Char.class, converter.getClass());
assertTrue(converter.canConvert("a", Character.class));
assertEquals(Character.valueOf('a'), converter.convert("a", Character.class));
converter = converters.getConverter("", Character.class);
assertNotNull(converter);
assertEquals(String2Char.class, converter.getClass());
assertTrue(converter.canConvert("", Character.class));
assertEquals(null, converter.convert("", Character.class));
converter = converters.getConverter("a", Character.TYPE);
assertNotNull(converter);
assertEquals(String2Char.class, converter.getClass());
assertTrue(converter.canConvert("a", Character.TYPE));
assertEquals(Character.valueOf('a'), converter.convert("a", Character.TYPE));
converter = converters.getConverter("", Character.TYPE);
assertNotNull(converter);
assertEquals(String2Char.class, converter.getClass());
assertTrue(converter.canConvert("", Character.TYPE));
assertEquals(Character.valueOf('\0'), converter.convert("", Character.TYPE));
converter = new String2Char(converters);
assertTrue(converter.canConvert(null, Character.class));
assertEquals(null, converter.convert(null, Character.class));
assertTrue(converter.canConvert(null, Character.TYPE));
Object result = converter.convert(null, Character.TYPE);
assertEquals(Character.valueOf('\0'), result);
try {
primitiveCharField.set(this, result);
} catch (Exception e) {
fail("Cannot set value of: " + primitiveCharField + " - " + e.toString());
}
}
///////////////////////////////////////////////////////////////////////////
// String2CharArray
@Test
public void testString2CharArray() {
// Character[]
Converter converter = converters.getConverter("abc", Character[].class);
assertNotNull(converter);
assertEquals(String2CharArray.class, converter.getClass());
assertTrue(converter.canConvert("abc", Character[].class));
Object result = converter.convert("abc", Character[].class);
assertEquals(Character[].class, result.getClass());
assertArrayEquals(arrayOfCharacter, (Character[])result);
try {
arrayOfCharacterField.set(this, result);
} catch (Exception e) {
fail("Cannot set value of: " + arrayOfCharacterField + " - " + e.toString());
}
// char[]
converter = converters.getConverter("abc", char[].class);
assertNotNull(converter);
assertEquals(String2CharArray.class, converter.getClass());
assertTrue(converter.canConvert("abc", char[].class));
result = converter.convert("abc", char[].class);
assertEquals(char[].class, result.getClass());
assertArrayEquals(arrayOfChar, (char[])result);
try {
arrayOfCharField.set(this, result);
} catch (Exception e) {
fail("Cannot set value of: " + arrayOfCharField + " - " + e.toString());
}
}
///////////////////////////////////////////////////////////////////////////
// String2Locale
@Test
public void testString2Locale() {
Converter converter = converters.getConverter("en", Locale.class);
assertNotNull(converter);
assertEquals(String2Locale.class, converter.getClass());
assertTrue(converter.canConvert("en", Locale.class));
Object result = converter.convert("en", Locale.class);
assertEquals(Locale.class, result.getClass());
assertEquals(Locale.ENGLISH, result);
assertTrue(((Reverter)converter).canRevert(result));
assertEquals("en", ((Reverter)converter).revert(result));
assertEquals("en", converters.revert(result));
converter = converters.getConverter("en_US", Locale.class);
assertNotNull(converter);
assertEquals(String2Locale.class, converter.getClass());
assertTrue(converter.canConvert("en_US", Locale.class));
result = converter.convert("en_US", Locale.class);
assertEquals(Locale.class, result.getClass());
assertEquals(result, Locale.US);
assertTrue(((Reverter)converter).canRevert(result));
assertEquals("en_US", ((Reverter)converter).revert(result));
assertEquals("en_US", converters.revert(result));
converter = converters.getConverter("es_ES_Traditional_WIN", Locale.class);
assertNotNull(converter);
assertEquals(String2Locale.class, converter.getClass());
assertTrue(converter.canConvert("es_ES_Traditional_WIN", Locale.class));
result = converter.convert("es_ES_Traditional_WIN", Locale.class);
assertEquals(Locale.class, result.getClass());
assertEquals(result, new Locale("es", "ES", "Traditional_WIN"));
assertTrue(((Reverter)converter).canRevert(result));
assertEquals("es_ES_Traditional_WIN", ((Reverter)converter).revert(result));
assertEquals("es_ES_Traditional_WIN", converters.revert(result));
}
///////////////////////////////////////////////////////////////////////////
// String2URI
@Test
public void testString2URI() {
Converter converter = converters.getConverter("http://www.graniteds.org", URI.class);
assertNotNull(converter);
assertEquals(String2URI.class, converter.getClass());
assertTrue(converter.canConvert("http://www.graniteds.org", URI.class));
Object result = converter.convert("http://www.graniteds.org", URI.class);
assertEquals(URI.class, result.getClass());
try {
assertEquals(new URI("http://www.graniteds.org"), result);
} catch (Exception e) {
fail(e.toString());
}
assertTrue(((Reverter)converter).canRevert(result));
assertEquals("http://www.graniteds.org", ((Reverter)converter).revert(result));
assertEquals("http://www.graniteds.org", converters.revert(result));
converter = converters.getConverter("http://www.graniteds.org", URL.class);
assertNotNull(converter);
assertEquals(String2URI.class, converter.getClass());
assertTrue(converter.canConvert("http://www.graniteds.org", URL.class));
result = converter.convert("http://www.graniteds.org", URL.class);
assertEquals(URL.class, result.getClass());
try {
assertEquals(new URL("http://www.graniteds.org"), result);
} catch (Exception e) {
fail(e.toString());
}
assertTrue(((Reverter)converter).canRevert(result));
assertEquals("http://www.graniteds.org", ((Reverter)converter).revert(result));
assertEquals("http://www.graniteds.org", converters.revert(result));
}
///////////////////////////////////////////////////////////////////////////
// String2Document
@Test
public void testString2Document() {
final String xmlString =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<doc attr=\"attr value\">\n" +
" <elt>blabla</elt>\n" +
"</doc>";
final XMLUtil xmlUtil = XMLUtilFactory.getXMLUtil();
final Document doc = xmlUtil.buildDocument(xmlString);
Converter converter = converters.getConverter(xmlString, Document.class);
assertNotNull(converter);
assertEquals(String2Document.class, converter.getClass());
assertTrue(converter.canConvert(xmlString, Document.class));
Object result = converter.convert(xmlString, Document.class);
assertTrue(result instanceof Document);
assertTrue(doc.isEqualNode((Document)result));
}
///////////////////////////////////////////////////////////////////////////
// Array2Array
@Test
public void testArray2Array() {
// Object[] -> String[]
Converter converter = converters.getConverter(arrayOfObjectString, String[].class);
assertNotNull(converter);
assertEquals(Array2Array.class, converter.getClass());
assertTrue(converter.canConvert(arrayOfObjectString, String[].class));
Object result = converter.convert(arrayOfObjectString, String[].class);
assertEquals(String[].class, result.getClass());
assertArrayEquals(arrayOfObjectString, (String[])result);
// Object[] -> Long[]
converter = converters.getConverter(arrayOfObjectNumber, Long[].class);
assertNotNull(converter);
assertEquals(Array2Array.class, converter.getClass());
assertTrue(converter.canConvert(arrayOfObjectNumber, Long[].class));
result = converter.convert(arrayOfObjectNumber, Long[].class);
assertEquals(Long[].class, result.getClass());
assertArrayEquals(arrayOfLong, (Long[])result);
// Object[] -> long[]
converter = converters.getConverter(arrayOfObjectNumber, long[].class);
assertNotNull(converter);
assertEquals(Array2Array.class, converter.getClass());
assertTrue(converter.canConvert(arrayOfObjectNumber, long[].class));
result = converter.convert(arrayOfObjectNumber, long[].class);
assertEquals(long[].class, result.getClass());
assertArrayEquals(arrayOfPrimitiveLong, (long[])result);
// Object[][] -> String[][]
Object[][] objects = new Object[][] {
{"abc", "def", ""},
{null, "yz"}
};
converter = converters.getConverter(objects, String[][].class);
assertNotNull(converter);
assertEquals(Array2Array.class, converter.getClass());
assertTrue(converter.canConvert(objects, String[][].class));
result = converter.convert(objects, String[][].class);
assertEquals(String[][].class, result.getClass());
assertArrayEquals(objects[0], ((String[][])result)[0]);
assertArrayEquals(objects[1], ((String[][])result)[1]);
}
///////////////////////////////////////////////////////////////////////////
// Collection2Array
@Test
public void testCollection2Array() {
// List<?> -> String[]
listOfWildcard = Arrays.asList(arrayOfObjectString);
Converter converter = converters.getConverter(listOfWildcard, String[].class);
assertNotNull(converter);
assertEquals(Collection2Array.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, String[].class));
Object result = converter.convert(listOfWildcard, String[].class);
assertEquals(String[].class, result.getClass());
assertArrayEquals(arrayOfObjectString, (String[])result);
// List<?> -> Long[]
listOfWildcard = Arrays.asList(arrayOfObjectNumber);
converter = converters.getConverter(listOfWildcard, Long[].class);
assertNotNull(converter);
assertEquals(Collection2Array.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, Long[].class));
result = converter.convert(listOfWildcard, Long[].class);
assertEquals(Long[].class, result.getClass());
assertArrayEquals(arrayOfLong, (Long[])result);
// List<?> -> long[]
converter = converters.getConverter(listOfWildcard, long[].class);
assertNotNull(converter);
assertEquals(Collection2Array.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, long[].class));
result = converter.convert(listOfWildcard, long[].class);
assertEquals(long[].class, result.getClass());
assertArrayEquals(arrayOfPrimitiveLong, (long[])result);
// Set<?> -> String[]
setOfWildcard = new HashSet<Object>(Arrays.asList(arrayOfObjectString));
converter = converters.getConverter(setOfWildcard, String[].class);
assertNotNull(converter);
assertEquals(Collection2Array.class, converter.getClass());
assertTrue(converter.canConvert(setOfWildcard, String[].class));
result = converter.convert(setOfWildcard, String[].class);
assertEquals(String[].class, result.getClass());
assertTrue(sameElements(arrayOfObjectString, (String[])result));
// Set<?> -> Long[]
setOfWildcard = new HashSet<Object>(Arrays.asList(arrayOfObjectNumber));
converter = converters.getConverter(setOfWildcard, Long[].class);
assertNotNull(converter);
assertEquals(Collection2Array.class, converter.getClass());
assertTrue(converter.canConvert(setOfWildcard, Long[].class));
result = converter.convert(setOfWildcard, Long[].class);
assertEquals(Long[].class, result.getClass());
assertTrue(sameElements(arrayOfLong, (Long[])result));
// Set<?> -> long[]
converter = converters.getConverter(setOfWildcard, long[].class);
assertNotNull(converter);
assertEquals(Collection2Array.class, converter.getClass());
assertTrue(converter.canConvert(setOfWildcard, long[].class));
result = converter.convert(setOfWildcard, long[].class);
assertEquals(long[].class, result.getClass());
assertTrue(sameElements(arrayOfPrimitiveLong, (long[])result));
// List<Set<Object>> -> String[][]
List<Set<Object>> list = new ArrayList<Set<Object>>();
list.add(new HashSet<Object>(Arrays.asList(new Object[]{"abc", "def", ""})));
list.add(new HashSet<Object>(Arrays.asList(new Object[]{null, "yz"})));
converter = converters.getConverter(list, String[][].class);
assertNotNull(converter);
assertEquals(Collection2Array.class, converter.getClass());
assertTrue(converter.canConvert(list, String[][].class));
result = converter.convert(list, String[][].class);
assertEquals(String[][].class, result.getClass());
assertTrue(sameElements(list.get(0).toArray(), ((String[][])result)[0]));
assertTrue(sameElements(list.get(1).toArray(), ((String[][])result)[1]));
}
///////////////////////////////////////////////////////////////////////////
// Collection2Collection
@Test
public void testCollection2Collection() {
// List<?> -> Collection (no conversion, same instance)
listOfWildcard = Arrays.asList(arrayOfObjectString);
Converter converter = converters.getConverter(listOfWildcard, Collection.class);
assertNotNull(converter);
assertEquals(Collection2Collection.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, Collection.class));
Object result = converter.convert(listOfWildcard, Collection.class);
assertTrue(listOfWildcard == result);
assertEquals(Arrays.asList(arrayOfObjectString), result);
// List<?> -> List (no conversion, same instance)
listOfWildcard = Arrays.asList(arrayOfObjectString);
converter = converters.getConverter(listOfWildcard, List.class);
assertNotNull(converter);
assertEquals(Collection2Collection.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, List.class));
result = converter.convert(listOfWildcard, List.class);
assertTrue(listOfWildcard == result);
assertEquals(Arrays.asList(arrayOfObjectString), result);
// Set<?> -> Collection (no conversion, same instance)
setOfWildcard = new HashSet<Object>(Arrays.asList(arrayOfObjectString));
converter = converters.getConverter(setOfWildcard, Collection.class);
assertNotNull(converter);
assertEquals(Collection2Collection.class, converter.getClass());
assertTrue(converter.canConvert(setOfWildcard, Collection.class));
result = converter.convert(setOfWildcard, Collection.class);
assertTrue(setOfWildcard == result);
assertEquals(new HashSet<Object>(Arrays.asList(arrayOfObjectString)), result);
// List<?> -> List<Object> (no conversion, same instance)
Type targetType = listOfObjectField.getGenericType();
listOfWildcard = Arrays.asList(arrayOfObjectString);
converter = converters.getConverter(listOfWildcard, targetType);
assertNotNull(converter);
assertEquals(Collection2Collection.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, targetType));
result = converter.convert(listOfWildcard, targetType);
assertTrue(listOfWildcard == result);
assertEquals(Arrays.asList(arrayOfObjectString), result);
// ArrayList<?> -> List<?> (no conversion, same instance)
targetType = listOfWildcardField.getGenericType();
listOfWildcard = Arrays.asList(arrayOfObjectString);
converter = converters.getConverter(listOfWildcard, targetType);
assertNotNull(converter);
assertEquals(Collection2Collection.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, targetType));
result = converter.convert(listOfWildcard, targetType);
assertTrue(listOfWildcard == result);
assertEquals(Arrays.asList(arrayOfObjectString), result);
// List<?> -> Set<Long> (collection + items conversions)
targetType = setOfLongField.getGenericType();
listOfWildcard = Arrays.asList(arrayOfObjectNumber);
converter = converters.getConverter(listOfWildcard, targetType);
assertNotNull(converter);
assertEquals(Collection2Collection.class, converter.getClass());
assertTrue(converter.canConvert(listOfWildcard, targetType));
result = converter.convert(listOfWildcard, targetType);
assertEquals(HashSet.class, result.getClass());
assertEquals(new HashSet<Long>(Arrays.asList(arrayOfLong)), result);
// Set<List<Object>> -> List<Set<String>>
Set<List<Object>> set = new HashSet<List<Object>>();
set.add(new ArrayList<Object>(Arrays.asList(new Object[]{"abc", "def", ""})));
set.add(new ArrayList<Object>(Arrays.asList(new Object[]{null, "yz"})));
targetType = listOfSetOfStringField.getGenericType();
converter = converters.getConverter(set, targetType);
assertNotNull(converter);
assertEquals(Collection2Collection.class, converter.getClass());
assertTrue(converter.canConvert(set, targetType));
result = converter.convert(set, targetType);
assertEquals(ArrayList.class, result.getClass());
assertEquals(HashSet.class, ((List<?>)result).get(0).getClass());
assertEquals(HashSet.class, ((List<?>)result).get(1).getClass());
boolean first = true;
int iMatch = 0;
for (List<?> list : set) {
if (first) {
first = false;
if (sameElements(list.toArray(), ((List<Set<?>>)result).get(0).toArray()))
iMatch = 0;
else if (sameElements(list.toArray(), ((List<Set<?>>)result).get(1).toArray()))
iMatch = 1;
else
fail("Cannot find a match between " + result + " and " + set);
}
else if (!sameElements(list.toArray(), ((List<Set<?>>)result).get((iMatch + 1) % 2).toArray()))
fail("Cannot find a match between " + result + " and " + set);
}
try {
listOfSetOfStringField.set(this, result);
for (Set<String> st : listOfSetOfString) {
for (String s : st)
assertTrue(s == null || s.length() >= 0);
}
} catch (Exception e) {
fail("Cannot set value of: " + listOfSetOfStringField + " - " + e.toString());
}
}
///////////////////////////////////////////////////////////////////////////
// Array2Collection
@Test
public void testArray2Collection() {
// Object[] -> Collection
Converter converter = converters.getConverter(arrayOfObjectString, Collection.class);
assertNotNull(converter);
assertEquals(Array2Collection.class, converter.getClass());
assertTrue(converter.canConvert(arrayOfObjectString, Collection.class));
Object result = converter.convert(arrayOfObjectString, Collection.class);
assertEquals(ArrayList.class, result.getClass());
assertEquals(Arrays.asList(arrayOfObjectString), result);
// String[] -> SortedSet
final String[] strings = {"f", "d", "e", "abc", "", "gds"};
converter = converters.getConverter(strings, SortedSet.class);
assertNotNull(converter);
assertEquals(Array2Collection.class, converter.getClass());
assertTrue(converter.canConvert(strings, SortedSet.class));
result = converter.convert(strings, SortedSet.class);
assertEquals(TreeSet.class, result.getClass());
assertEquals(new TreeSet<Object>(Arrays.asList(strings)), result);
// Object[] -> Set<Long> (collection + items conversions)
Type targetType = setOfLongField.getGenericType();
converter = converters.getConverter(arrayOfObjectNumber, targetType);
assertNotNull(converter);
assertEquals(Array2Collection.class, converter.getClass());
assertTrue(converter.canConvert(arrayOfObjectNumber, targetType));
result = converter.convert(arrayOfObjectNumber, targetType);
assertEquals(HashSet.class, result.getClass());
assertEquals(new HashSet<Long>(Arrays.asList(arrayOfLong)), result);
// Object[][] -> List<Set<String>>
Object[][] objects = new Object[][]{
{"abc", "def", ""},
{null, "yz"}
};
targetType = listOfSetOfStringField.getGenericType();
converter = converters.getConverter(objects, targetType);
assertNotNull(converter);
assertEquals(Array2Collection.class, converter.getClass());
assertTrue(converter.canConvert(objects, targetType));
result = converter.convert(objects, targetType);
assertEquals(ArrayList.class, result.getClass());
assertEquals(HashSet.class, ((List<?>)result).get(0).getClass());
assertEquals(HashSet.class, ((List<?>)result).get(1).getClass());
boolean first = true;
int iMatch = 0;
for (Object[] oo : objects) {
if (first) {
first = false;
if (sameElements(oo, ((List<Set<?>>)result).get(0).toArray()))
iMatch = 0;
else if (sameElements(oo, ((List<Set<?>>)result).get(1).toArray()))
iMatch = 1;
else
fail("Cannot find a match between " + result + " and " + Arrays.toString(objects));
}
else if (!sameElements(oo, ((List<Set<?>>)result).get((iMatch + 1) % 2).toArray()))
fail("Cannot find a match between " + result + " and " + Arrays.toString(objects));
}
try {
listOfSetOfStringField.set(this, result);
for (Set<String> st : listOfSetOfString) {
for (String s : st)
assertTrue(s == null || s.length() >= 0);
}
} catch (Exception e) {
fail("Cannot set value of: " + listOfSetOfStringField + " - " + e.toString());
}
}
///////////////////////////////////////////////////////////////////////////
// Map2Map
@Test
public void testMap2Map() {
Map<Object, Object> map = new HashMap<Object, Object>();
map.put("one", Byte.valueOf((byte)1));
map.put("ten", BigDecimal.TEN);
map.put(null, null);
map.put("one hundred twenty three", Integer.valueOf(123));
map.put("zero", BigInteger.ZERO);
Type targetType = mapOfStringIntegerField.getGenericType();
Converter converter = converters.getConverter(map, targetType);
assertNotNull(converter);
assertEquals(Map2Map.class, converter.getClass());
assertTrue(converter.canConvert(map, targetType));
Object result = converter.convert(map, targetType);
assertEquals(HashMap.class, result.getClass());
for (Map.Entry<?, ?> entry : ((Map<?, ?>)result).entrySet()) {
assertTrue(entry.getKey() == null || entry.getKey() instanceof String);
assertTrue(entry.getValue() == null || entry.getValue() instanceof Integer);
}
try {
mapOfStringIntegerField.set(this, result);
} catch (Exception e) {
fail("Cannot set value of: " + mapOfStringIntegerField + " - " + e.toString());
}
}
///////////////////////////////////////////////////////////////////////////
// Compatibility
public static interface I {/**/}
public static class A implements I {/**/}
public static class B extends A {/**/}
public static class C<T> {C<? extends T> c = this;}
public static class D<T> {D<T> d = this;}
@SuppressWarnings("all")
public static abstract class AbstractParent<T extends AbstractParent> {
T parent;
public T getParent() {
return parent;
}
public void setParent(T parent) {
this.parent = parent;
}
}
@SuppressWarnings("all")
public static class Child extends AbstractParent {/**/}
public static class SubChild extends AbstractParent<Child> {/**/}
@Test
public void testCompatibility() {
A a = new A();
B b = new B();
C<A> ca = new C<A>();
D<A> da = new D<A>();
Converter converter = converters.getConverter(b, A.class);
assertNotNull(converter);
assertEquals(Compatibility.class, converter.getClass());
assertTrue(converter.canConvert(b, A.class));
Object result = converter.convert(b, A.class);
assertTrue(b == result);
SubChild c = new SubChild();
c.setParent(new Child());
Type targetType = null;
try {
targetType = c.getClass().getSuperclass().getDeclaredField("parent").getGenericType();
} catch (Exception e) {
fail("Could not get 'parent' field type in: " + c);
}
converter = converters.getConverter(c, targetType);
assertNotNull(converter);
assertEquals(Compatibility.class, converter.getClass());
assertTrue(converter.canConvert(c, targetType));
result = converter.convert(c, targetType);
assertTrue(result == c);
// test whether Compatibility converter is found for wildcarded generic field C.c
try {
targetType = C.class.getDeclaredField("c").getGenericType();
}
catch (NoSuchFieldException e) {
fail("Could not get field 'c' in class: " + C.class);
}
converter = converters.getConverter(ca.c, targetType);
assertNotNull(converter);
assertEquals(Compatibility.class, converter.getClass());
result = converter.convert(ca.c, targetType);
assertTrue(result == ca.c);
// test whether Compatibility converter is found for generic field D.d
try {
targetType = D.class.getDeclaredField("d").getGenericType();
}
catch (NoSuchFieldException e) {
fail("Could not get field 'd' in class: " + D.class);
}
converter = converters.getConverter(da.d, targetType);
assertNotNull(converter);
assertEquals(Compatibility.class, converter.getClass());
result = converter.convert(da.d, targetType);
assertTrue(result == da.d);
}
///////////////////////////////////////////////////////////////////////////
// Utilities.
private static boolean sameElements(Object[] a1, Object[] a2) {
if (a1.length != a2.length)
return false;
List<?> l2 = new ArrayList<Object>(Arrays.asList(a2));
for (Object o1 : a1) {
if (!l2.remove(o1))
return false;
}
return l2.isEmpty(); // cannot be false, anyway...
}
@SuppressWarnings("boxing")
private static boolean sameElements(long[] a1, long[] a2) {
if (a1.length != a2.length)
return false;
long[] aa2 = new long[a2.length];
System.arraycopy(a2, 0, aa2, 0, a2.length);
for (long o1 : a1) {
boolean found = false;
for (int i = 0; i < aa2.length; i++) {
if (o1 == aa2[i]) {
long[] tmp = new long[aa2.length - 1];
if (i > 0)
System.arraycopy(aa2, 0, tmp, 0, i);
if (i < tmp.length)
System.arraycopy(aa2, i+1, tmp, i, tmp.length - i);
aa2 = tmp;
found = true;
break;
}
}
if (!found)
return false;
}
return aa2.length == 0; // cannot be false, anyway...
}
private static interface DirectConverter {
public Object convert(Object o);
}
}