blob: 9b4615ef8efb39c9848448cc91f6f13060c82869 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.osgi.util.converter;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Array;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Deque;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Queue;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.Version;
import org.osgi.util.converter.MyDTO.Count;
import org.osgi.util.converter.MyEmbeddedDTO.Alpha;
public class ConverterTest {
private Converter converter;
@Before
public void setUp() {
converter = Converters.standardConverter();
}
@After
public void tearDown() {
converter = null;
}
@Test
public void testVersion() {
Version v =new Version(1,2,3,"qualifier");
Converter c = Converters.standardConverter();
String s = c.convert(v).to(String.class);
Version v2 = c.convert(s).to(Version.class);
assertEquals(v, v2);
}
@Test
public void testSimpleConversions() {
// Conversions to String
assertEquals("abc", converter.convert("abc").to(String.class));
assertEquals("true", converter.convert(Boolean.TRUE).to(String.class));
assertEquals("c", converter.convert('c').to(String.class));
assertEquals("123", converter.convert(123).to(String.class));
assertEquals("" + Long.MAX_VALUE, converter.convert(Long.MAX_VALUE).to(String.class));
assertEquals("12.3", converter.convert(12.3f).to(String.class));
assertEquals("12.345", converter.convert(12.345d).to(String.class));
assertNull(converter.convert(null).to(String.class));
assertNull(converter.convert(Collections.emptyList()).to(String.class));
String bistr = "999999999999999999999"; // more than Long.MAX_VALUE
assertEquals(bistr, converter.convert(new BigInteger(bistr)).to(String.class));
// Conversions to boolean
assertTrue(converter.convert("true").to(boolean.class));
assertTrue(converter.convert("TRUE").to(boolean.class));
assertTrue(converter.convert('x').to(boolean.class));
assertTrue(converter.convert(Long.MIN_VALUE).to(boolean.class));
assertTrue(converter.convert(72).to(boolean.class));
assertFalse(converter.convert("false").to(boolean.class));
assertFalse(converter.convert("bleh").to(boolean.class));
assertFalse(converter.convert((char) 0).to(boolean.class));
assertFalse(converter.convert(null).to(boolean.class));
assertFalse(converter.convert(Collections.emptyList()).to(boolean.class));
// Conversions to integer
assertEquals(Integer.valueOf(123), converter.convert("123").to(int.class));
assertEquals(1, (int) converter.convert(true).to(int.class));
assertEquals(0, (int) converter.convert(false).to(int.class));
assertEquals(65, (int) converter.convert('A').to(int.class));
// Conversions to long
assertEquals(Long.valueOf(65), converter.convert('A').to(Long.class));
// Conversions to Class
assertEquals(BigDecimal.class, converter.convert("java.math.BigDecimal").to(Class.class));
assertEquals(BigDecimal.class, converter.convert("java.math.BigDecimal").to(new TypeReference<Class<?>>() {}));
assertNull(converter.convert(null).to(Class.class));
assertNull(converter.convert(Collections.emptyList()).to(Class.class));
assertEquals(Integer.valueOf(123), converter.convert("123").to(Integer.class));
assertEquals(Long.valueOf(123), converter.convert("123").to(Long.class));
assertEquals('1', (char) converter.convert("123").to(Character.class));
assertEquals('Q', (char) converter.convert(null).defaultValue('Q').to(Character.class));
assertEquals((char) 123, (char) converter.convert(123L).to(Character.class));
assertEquals((char) 123, (char) converter.convert(123).to(Character.class));
assertEquals(Byte.valueOf((byte) 123), converter.convert("123").to(Byte.class));
assertEquals(Float.valueOf("12.3"), converter.convert("12.3").to(Float.class));
assertEquals(Double.valueOf("12.3"), converter.convert("12.3").to(Double.class));
}
@Test
public void testCharAggregateToString() {
Converter c = Converters.newConverterBuilder().
rule(new Rule<List<Character>, String>(ConverterTest::characterListToString) {}).
rule(new Rule<String, List<Character>>(ConverterTest::stringToCharacterList) {}).
build();
char[] ca = new char[] {'h', 'e', 'l', 'l', 'o'};
assertEquals("hello", c.convert(ca).to(String.class));
Character[] ca2 = c.convert(ca).to(Character[].class);
assertEquals("hello", c.convert(ca2).to(String.class));
List<Character> cl = c.convert(ca).to(new TypeReference<List<Character>>() {});
assertEquals("hello", c.convert(cl).to(String.class));
// And back
assertArrayEquals(ca, c.convert("hello").to(char[].class));
assertArrayEquals(ca2, c.convert("hello").to(Character[].class));
assertEquals(cl, c.convert("hello").to(new TypeReference<List<Character>>() {}));
}
private static String characterListToString(List<Character> cl) {
StringBuilder sb = new StringBuilder(cl.size());
for (char c : cl) {
sb.append(c);
}
return sb.toString();
}
private static List<Character> stringToCharacterList(String s) {
List<Character> lc = new ArrayList<>();
for (int i=0; i<s.length(); i++) {
lc.add(s.charAt(i));
}
return lc;
}
enum TestEnum { FOO, BAR, BLAH, FALSE, X};
enum TestEnum2 { BLAH };
@Test
public void testEnums() {
assertSame(TestEnum.BLAH, converter.convert("BLAH").to(TestEnum.class));
assertSame(TestEnum.X, converter.convert('X').to(TestEnum.class));
assertSame(TestEnum.FALSE, converter.convert(false).to(TestEnum.class));
assertSame(TestEnum.BAR, converter.convert(1).to(TestEnum.class));
assertSame(TestEnum.BLAH, converter.convert(TestEnum2.BLAH).to(TestEnum.class));
assertNull(converter.convert(null).to(TestEnum.class));
assertNull(converter.convert(Collections.emptySet()).to(TestEnum.class));
}
@Test
public void testToReflectType() {
Type t = TestEnum.class;
TestEnum e = converter.convert("X").to(t);
assertEquals(TestEnum.X, e);
}
@Test
public void testIdentialTarget() {
Object o = new Object();
assertSame(o, converter.convert(o).to(Object.class));
Thread t = new Thread(); // No converter available
assertSame(t, converter.convert(t).to(Thread.class));
assertSame(t, converter.convert(t).to(Runnable.class));
assertSame(t, converter.convert(t).to(Object.class));
Thread st = new Thread() {}; // Subclass of Thread
assertSame(st, converter.convert(st).to(Thread.class));
}
@Test
public void testFromUnknownDataTypeViaString() {
class MyClass {
@Override
public String toString() {
return "1234";
}
};
MyClass o = new MyClass();
assertEquals(1234, (int) converter.convert(o).to(int.class));
assertEquals("1234", converter.convert(o).to(String.class));
}
@Test
public void testToUnknownViaStringCtor() {
class MyClass {
@Override
public String toString() {
return "http://127.0.0.1:1234/blah";
}
};
MyClass o = new MyClass();
URL url = converter.convert(o).to(URL.class);
assertEquals("http://127.0.0.1:1234/blah", url.toString());
assertEquals("http", url.getProtocol());
assertEquals("127.0.0.1", url.getHost());
assertEquals(1234, url.getPort());
assertEquals("/blah", url.getPath());
assertNull(converter.convert(null).to(URL.class));
assertNull(converter.convert(Collections.emptyList()).to(URL.class));
}
@Test
public void testFromMultiToSingle() {
assertEquals("abc", converter.convert(Collections.singleton("abc")).to(String.class));
assertEquals("abc", converter.convert(Arrays.asList("abc", "def", "ghi")).to(String.class));
assertEquals(42, (int) converter.convert(Arrays.asList("42", "17")).to(Integer.class));
MyClass2 mc = converter.convert(new String[] {"xxx", "yyy", "zzz"}).to(MyClass2.class);
assertEquals("xxx", mc.toString());
MyClass2[] arr = new MyClass2[] {new MyClass2("3.1412"), new MyClass2("6.2824")};
assertEquals(Float.valueOf(3.1412f), Float.valueOf(converter.convert(arr).to(float.class)));
}
@Test
public void testFromListToSet() {
List<Object> l = new ArrayList<>(Arrays.asList("A", 'B', 333));
Set<?> s = converter.convert(l).to(Set.class);
assertEquals(3, s.size());
for (Object o : s) {
Object expected = l.remove(0);
assertEquals(expected, o);
}
}
@Test
public void testFromGenericSetToLinkedList() {
Set<Integer> s = new LinkedHashSet<>();
s.add(123);
s.add(456);
LinkedList<String> ll = converter.convert(s).to(new TypeReference<LinkedList<String>>() {});
assertEquals(Arrays.asList("123", "456"), ll);
}
@Test
public void testFromArrayToGenericOrderPreservingSet() {
String[] sa = {"567", "-765", "0", "-900"};
// Returned set should be order preserving
Set<Long> s = converter.convert(sa).to(new TypeReference<Set<Long>>() {});
List<String> sl = new ArrayList<>(Arrays.asList(sa));
for (long l : s) {
long expected = Long.parseLong(sl.remove(0));
assertEquals(expected, l);
}
}
@Test
public void testFromSetToArray() {
Set<Integer> s = new LinkedHashSet<>();
s.add(Integer.MIN_VALUE);
long[] la = converter.convert(s).to(long[].class);
assertEquals(1, la.length);
assertEquals(Integer.MIN_VALUE, la[0]);
}
@Test
public void testStringArrayToIntegerArray() {
String[] sa = {"999", "111", "-909"};
Integer[] ia = converter.convert(sa).to(Integer[].class);
assertEquals(3, ia.length);
assertArrayEquals(new Integer[] {999, 111, -909}, ia);
}
@Test
public void testCharArrayConversion() {
char[] ca = converter.convert(new int[] {9,8,7}).to(char[].class);
assertArrayEquals(new char[] {9,8,7}, ca);
Character[] ca2 = converter.convert((long) 17).to(Character[].class);
assertArrayEquals(new Character[] {(char)17}, ca2);
char[] ca3 = converter.convert(new short[] {257}).to(char[].class);
assertArrayEquals(new char[] {257}, ca3);
char c = converter.convert(new char[] {'x', 'y'}).to(char.class);
assertEquals('x', c);
char[] ca4a = {'x', 'y'};
char[] ca4b = converter.convert(ca4a).to(char[].class);
assertArrayEquals(new char [] {'x', 'y'}, ca4b);
assertNotSame("Should have created a new instance", ca4a, ca4b);
}
/**
* 707.4.3.1 - null becomes an empty array
*/
@Test
public void testNullToArrayConversion() {
checkArray(String[].class);
checkArray(boolean[].class);
checkArray(byte[].class);
checkArray(short[].class);
checkArray(char[].class);
checkArray(int[].class);
checkArray(float[].class);
checkArray(long[].class);
checkArray(double[].class);
checkArray(String[][].class);
checkArray(boolean[][].class);
checkArray(byte[][].class);
checkArray(short[][].class);
checkArray(char[][].class);
checkArray(int[][].class);
checkArray(float[][].class);
checkArray(long[][].class);
checkArray(double[][].class);
checkArray(String[][][].class);
checkArray(boolean[][][].class);
checkArray(byte[][][].class);
checkArray(short[][][].class);
checkArray(char[][][].class);
checkArray(int[][][].class);
checkArray(float[][][].class);
checkArray(long[][][].class);
checkArray(double[][][].class);
}
private void checkArray(Class<?> arrayType) {
assertTrue(arrayType.isArray());
Object array = converter.convert(null).to(arrayType);
assertEquals(0, Array.getLength(array));
assertTrue(arrayType.isInstance(array));
}
@Test
public void testLongCollectionConversion() {
long[] l = converter.convert(Long.MAX_VALUE).to(long[].class);
assertArrayEquals(new long[] {Long.MAX_VALUE}, l);
Long[] l2 = converter.convert(Long.MAX_VALUE).to(Long[].class);
assertArrayEquals(new Long[] {Long.MAX_VALUE}, l2);
List<Long> ll = converter.convert(new long[] {Long.MIN_VALUE, Long.MAX_VALUE}).to(new TypeReference<List<Long>>() {});
assertEquals(Arrays.asList(Long.MIN_VALUE, Long.MAX_VALUE), ll);
List<Long> ll2 = converter.convert(Arrays.asList(123, 345)).to(new TypeReference<List<Long>>() {});
assertEquals(Arrays.asList(123L, 345L), ll2);
}
@Test
public void testExceptionDefaultValue() {
assertEquals(42, (int) converter.convert("haha").defaultValue(42).to(int.class));
assertEquals(999, (int) converter.convert("haha").defaultValue(999).to(int.class));
try {
converter.convert("haha").to(int.class);
fail("Should have thrown an exception");
} catch (ConversionException ex) {
// good
}
}
@Test
public void testStandardStringArrayConversion() {
String[] sa = {"A", "B"};
assertEquals("A", converter.convert(sa).toString());
assertEquals("A", converter.convert(sa).to(String.class));
String[] sa2 = {"A"};
assertArrayEquals(sa2, converter.convert("A").to(String[].class));
}
@Test
public void testCustomStringArrayConversion() {
ConverterBuilder cb = converter.newConverterBuilder();
cb.rule(new Rule<String[],String>(v -> Stream.of(v).collect(Collectors.joining(","))){});
cb.rule(new Rule<String,String[]>(v -> v.split(",")){});
Converter adapted = cb.build();
String[] sa = {"A", "B"};
assertEquals("A,B", adapted.convert(sa).to(String.class));
assertArrayEquals(sa, adapted.convert("A,B").to(String[].class));
}
@Test
public void testCustomIntArrayConversion() {
ConverterBuilder cb = converter.newConverterBuilder();
cb.rule(String.class, (f,t) -> f instanceof int[] ? Arrays.stream((int []) f).mapToObj(Integer::toString).collect(Collectors.joining(",")) : null);
cb.rule(int[].class, (f,t) -> f instanceof String ? Arrays.stream(((String) f).split(",")).mapToInt(Integer::parseInt).toArray() : null);
Converter adapted = cb.build();
int[] ia = {1, 2};
assertEquals("1,2", adapted.convert(ia).to(String.class));
assertArrayEquals(ia, adapted.convert("1,2").to(int[].class));
}
@Test
public void testCustomConverterChaining() {
ConverterBuilder cb = converter.newConverterBuilder();
cb.rule(Date.class,
(f,t) -> f instanceof String ? new Date(0) : ConverterFunction.CANNOT_HANDLE);
Converter c1 = cb.build();
assertEquals(new Date(0), c1.convert("something").to(Date.class));
assertEquals(new Date(0), c1.convert("foo").to(Date.class));
ConverterBuilder cb2 = c1.newConverterBuilder();
cb2.rule(Date.class,
(f,t) -> f.equals("foo") ? new Date(100000) : ConverterFunction.CANNOT_HANDLE);
Converter c2 = cb2.build();
assertEquals(new Date(0), c2.convert("something").to(Date.class));
assertEquals(new Date(100000), c2.convert("foo").to(Date.class));
}
@Test
public void testCustomErrorHandling() {
ConverterFunction func = new ConverterFunction() {
@Override
public Object apply(Object obj, Type targetType) {
if ("hello".equals(obj)) {
return -1;
}
if ("goodbye".equals(obj)) {
return null;
}
return ConverterFunction.CANNOT_HANDLE;
}
};
ConverterBuilder cb = converter.newConverterBuilder();
Converter adapted = cb.errorHandler(func).build();
assertEquals(new Integer(12), adapted.convert("12").to(Integer.class));
assertEquals(new Integer(-1), adapted.convert("hello").to(Integer.class));
assertNull(adapted.convert("goodbye").to(Integer.class));
try {
adapted.convert("nothing").to(Integer.class);
fail("Should have thrown a Conversion Exception when converting 'hello' to a number");
} catch (ConversionException ce) {
// good
}
// This is with the non-adapted converter
try {
converter.convert("hello").to(Integer.class);
fail("Should have thrown a Conversion Exception when converting 'hello' to a number");
} catch (ConversionException ce) {
// good
}
}
@Test
public void testCustomErrorHandlingProxy() {
ConverterFunction errHandler = new ConverterFunction() {
@Override
public Object apply(Object obj, Type targetType) throws Exception {
return 123;
}
};
ConverterBuilder cb = converter.newConverterBuilder();
Converter c = cb.errorHandler(errHandler).build();
Map<?,?> m = new HashMap<>();
MyIntf i = c.convert(m).to(MyIntf.class);
assertEquals(123, i.value());
}
@Test
public void testMultipleCustomErrorHandling() {
ConverterBuilder cb1 = converter.newConverterBuilder();
ConverterFunction func1 = new ConverterFunction() {
@Override
public Object apply(Object obj, Type targetType) {
return -1;
}
};
cb1.errorHandler(func1);
Converter c1 = cb1.build();
ConverterBuilder cb2 = c1.newConverterBuilder();
ConverterFunction func2 = new ConverterFunction() {
@Override
public Object apply(Object obj, Type targetType) {
if ("hello".equals(obj)) {
return 0;
}
return ConverterFunction.CANNOT_HANDLE;
}
};
cb2.errorHandler(func2);
Converter adapted = cb2.build();
assertEquals(Integer.valueOf(0), adapted.convert("hello").to(Integer.class));
assertEquals(Integer.valueOf(-1), adapted.convert("bye").to(Integer.class));
}
static class MyConverterFunction implements ConverterFunction {
@Override
public Object apply(Object obj, Type targetType) throws Exception {
if ("hello".equals(obj)) {
return 0;
}
return ConverterFunction.CANNOT_HANDLE;
}
}
@Test
public void testUUIDConversion() {
UUID uuid = UUID.randomUUID();
String s = converter.convert(uuid).to(String.class);
assertTrue("UUID should be something", s.length() > 0);
UUID uuid2 = converter.convert(s).to(UUID.class);
assertEquals(uuid, uuid2);
}
@Test
public void testPatternConversion() {
String p = "\\S*";
Pattern pattern = converter.convert(p).to(Pattern.class);
Matcher matcher = pattern.matcher("hi");
assertTrue(matcher.matches());
String p2 = converter.convert(pattern).to(String.class);
assertEquals(p, p2);
}
@Test
public void testLocalDateTime() {
LocalDateTime ldt = LocalDateTime.now();
String s = converter.convert(ldt).to(String.class);
assertTrue(s.length() > 0);
LocalDateTime ldt2 = converter.convert(s).to(LocalDateTime.class);
assertEquals(ldt, ldt2);
}
@Test
public void testLocalDate() {
LocalDate ld = LocalDate.now();
String s = converter.convert(ld).to(String.class);
assertTrue(s.length() > 0);
LocalDate ld2 = converter.convert(s).to(LocalDate.class);
assertEquals(ld, ld2);
}
@Test
public void testLocalTime() {
LocalTime lt = LocalTime.now();
String s = converter.convert(lt).to(String.class);
assertTrue(s.length() > 0);
LocalTime lt2 = converter.convert(s).to(LocalTime.class);
assertEquals(lt, lt2);
}
@Test
public void testOffsetDateTime() {
OffsetDateTime ot = OffsetDateTime.now();
String s = converter.convert(ot).to(String.class);
assertTrue(s.length() > 0);
OffsetDateTime ot2 = converter.convert(s).to(OffsetDateTime.class);
assertEquals(ot, ot2);
}
@Test
public void testOffsetTime() {
OffsetTime ot = OffsetTime.now();
String s = converter.convert(ot).to(String.class);
assertTrue(s.length() > 0);
OffsetTime ot2 = converter.convert(s).to(OffsetTime.class);
assertEquals(ot, ot2);
}
@Test
public void testZonedDateTime() {
ZonedDateTime zdt = ZonedDateTime.now();
String s = converter.convert(zdt).to(String.class);
assertTrue(s.length() > 0);
ZonedDateTime zdt2 = converter.convert(s).to(ZonedDateTime.class);
assertEquals(zdt, zdt2);
}
@Test
public void testInstant() {
Instant i = Instant.now();
String s = converter.convert(i).to(String.class);
assertTrue(s.length() > 0);
Instant i2 = converter.convert(s).to(Instant.class);
assertEquals(i, i2);
}
@Test
public void testMonthDay() {
MonthDay md = MonthDay.of(Month.APRIL, 1);
String s = converter.convert(md).to(String.class);
assertTrue(s.length() > 0);
MonthDay md2 = converter.convert(s).to(MonthDay.class);
assertEquals(md, md2);
}
@Test
public void testYearMonth() {
YearMonth ym = YearMonth.of(1999, Month.APRIL);
String s = converter.convert(ym).to(String.class);
assertTrue(s.length() > 0);
YearMonth ym2 = converter.convert(s).to(YearMonth.class);
assertEquals(ym, ym2);
}
@Test
public void testYear() {
Year y = Year.of(1999);
String s = converter.convert(y).to(String.class);
assertTrue(s.length() > 0);
Year y2 = converter.convert(s).to(Year.class);
assertEquals(y, y2);
}
@Test
public void testDuration() {
Duration d = Duration.ofSeconds(42);
String s = converter.convert(d).to(String.class);
assertTrue(s.length() > 0);
Duration d2 = converter.convert(s).to(Duration.class);
assertEquals(d, d2);
}
@Test
public void testCalendarDate() {
Calendar cal = new GregorianCalendar(1971, 1, 13, 12, 37, 41);
TimeZone tz =TimeZone.getTimeZone("CET");
cal.setTimeZone(tz);
Date d = cal.getTime();
Converter c = converter;
String s = c.convert(d).toString();
assertEquals("1971-02-13T11:37:41Z", s);
assertEquals(d, c.convert(s).to(Date.class));
String s2 = c.convert(cal).toString();
assertEquals("1971-02-13T11:37:41Z", s2);
Calendar cal2 = c.convert(s2).to(Calendar.class);
assertEquals(cal.getTime(), cal2.getTime());
}
@Test
public void testCalendarLong() {
Calendar cal = new GregorianCalendar(1971, 1, 13, 12, 37, 41);
TimeZone tz =TimeZone.getTimeZone("UTC");
cal.setTimeZone(tz);
long l = converter.convert(cal).to(Long.class);
assertEquals(l, cal.getTimeInMillis());
Calendar cal2 = converter.convert(l).to(Calendar.class);
assertEquals(cal.getTime(), cal2.getTime());
}
@Test
public void testDefaultValue() {
long l = converter.convert(null).defaultValue("12").to(Long.class);
assertEquals(12L, l);
assertNull(converter.convert("haha").defaultValue(null).to(Integer.class));
assertNull(converter.convert("test").defaultValue(null).to(new TypeReference<List<Long>>() {}));
}
@Test
public void testDTO2Map() {
MyEmbeddedDTO embedded = new MyEmbeddedDTO();
embedded.marco = "hohoho";
embedded.polo = Long.MAX_VALUE;
embedded.alpha = Alpha.A;
MyDTO dto = new MyDTO();
dto.ping = "lalala";
dto.pong = Long.MIN_VALUE;
dto.count = Count.ONE;
dto.embedded = embedded;
@SuppressWarnings("rawtypes")
Map m = converter.convert(dto).to(Map.class);
assertEquals(4, m.size());
assertEquals("lalala", m.get("ping"));
assertEquals(Long.MIN_VALUE, m.get("pong"));
assertEquals(Count.ONE, m.get("count"));
assertNotNull(m.get("embedded"));
MyEmbeddedDTO e = (MyEmbeddedDTO) m.get("embedded");
assertEquals("hohoho", e.marco);
assertEquals(Long.MAX_VALUE, e.polo);
assertEquals(Alpha.A, e.alpha);
}
@Test
public void testDTO2Map2() {
MyEmbeddedDTO embedded = new MyEmbeddedDTO();
embedded.marco = "hohoho";
embedded.polo = Long.MAX_VALUE;
embedded.alpha = Alpha.A;
MyDTO dto = new MyDTO();
dto.ping = "lalala";
dto.pong = Long.MIN_VALUE;
dto.count = Count.ONE;
dto.embedded = embedded;
@SuppressWarnings("rawtypes")
Map m = converter.convert(dto).sourceAsDTO().to(Map.class);
assertEquals(4, m.size());
assertEquals("lalala", m.get("ping"));
assertEquals(Long.MIN_VALUE, m.get("pong"));
assertEquals(Count.ONE, m.get("count"));
assertNotNull(m.get("embedded"));
MyEmbeddedDTO e = (MyEmbeddedDTO) m.get("embedded");
assertEquals("hohoho", e.marco);
assertEquals(Long.MAX_VALUE, e.polo);
assertEquals(Alpha.A, e.alpha);
/* TODO this is the way it was, but it does not seem right
Map e = (Map)m.get("embedded");
assertEquals("hohoho", e.get("marco"));
assertEquals(Long.MAX_VALUE, e.get("polo"));
assertEquals(Alpha.A, e.get("alpha"));
*/
}
@Test
public void testDTO2Map3() {
MyEmbeddedDTO embedded2 = new MyEmbeddedDTO();
embedded2.marco = "hohoho";
embedded2.polo = Long.MAX_VALUE;
embedded2.alpha = Alpha.A;
MyDTOWithMethods embedded = new MyDTOWithMethods();
embedded.ping = "lalala";
embedded.pong = Long.MIN_VALUE;
embedded.count = Count.ONE;
embedded.embedded = embedded2;
MyDTO8 dto = new MyDTO8();
dto.ping = "lalala";
dto.pong = Long.MIN_VALUE;
dto.count = MyDTO8.Count.ONE;
dto.embedded = embedded;
@SuppressWarnings("rawtypes")
Map m = converter.convert(dto).sourceAsDTO().to(Map.class);
assertEquals(4, m.size());
assertEquals("lalala", m.get("ping"));
assertEquals(Long.MIN_VALUE, m.get("pong"));
assertEquals(MyDTO8.Count.ONE, m.get("count"));
assertNotNull(m.get("embedded"));
assertTrue(m.get( "embedded" ) instanceof MyDTOWithMethods);
MyDTOWithMethods e = (MyDTOWithMethods)m.get("embedded");
assertEquals("lalala", e.ping);
assertEquals(Long.MIN_VALUE, e.pong);
assertEquals(Count.ONE, e.count);
assertNotNull(e.embedded);
assertTrue(e.embedded instanceof MyEmbeddedDTO);
MyEmbeddedDTO e2 = e.embedded;
assertEquals("hohoho", e2.marco);
assertEquals(Long.MAX_VALUE, e2.polo);
assertEquals(Alpha.A, e2.alpha);
}
@Test
public void testDTO2Map4() {
MyDefaultCtorDTOAlike dto = new MyDefaultCtorDTOAlike();
dto.myProp = "myValue";
@SuppressWarnings("rawtypes")
Map m = converter.convert(dto).to(Map.class);
assertEquals(1, m.size());
assertEquals("myValue", m.get("myProp"));
}
@Test
public void testDTO2Map5() {
MyDTO3 dto = new MyDTO3();
dto.charSet = new HashSet<>(Arrays.asList('f', 'o', 'o'));
@SuppressWarnings("rawtypes")
Map m = converter.convert(dto).to(new TypeReference<Map<String, ?>>() {});
assertEquals(1, m.size());
assertEquals(dto.charSet, m.get("charSet"));
m = converter.convert(dto).to(new TypeReference<Map<String, ? extends List<String>>>() {});
assertEquals(1, m.size());
List<String> list = new ArrayList<>();
for (Character character : dto.charSet) {
list.add(String.valueOf(character));
}
assertEquals(list, m.get("charSet"));
}
@Test @SuppressWarnings({ "rawtypes", "unchecked" })
public void testDTOFieldShadowing() {
MySubDTO dto = new MySubDTO();
dto.ping = "test";
dto.count = Count.THREE;
Map m = converter.convert(dto).to(new TypeReference<Map<String,String>>() {});
Map<String, String> expected = new HashMap<>();
expected.put("ping", "test");
expected.put("count", "THREE");
expected.put("pong", "0");
expected.put("embedded", null);
assertEquals(expected, new HashMap<String, String>(m));
MySubDTO dto2 = converter.convert(m).to(MySubDTO.class);
assertEquals("test", dto2.ping);
assertEquals(Count.THREE, dto2.count);
assertEquals(0L, dto2.pong);
assertNull(dto2.embedded);
}
@Test
public void testMap2DTO() {
Map<String, Object> m = new HashMap<>();
m.put("ping", "abc xyz");
m.put("pong", 42L);
m.put("count", Count.ONE);
Map<String, Object> e = new HashMap<>();
e.put("marco", "ichi ni san");
e.put("polo", 64L);
e.put("alpha", Alpha.A);
m.put("embedded", e);
MyDTO dto = converter.convert(m).to(MyDTO.class);
assertEquals("abc xyz", dto.ping);
assertEquals(42L, dto.pong);
assertEquals(Count.ONE, dto.count);
assertNotNull(dto.embedded);
assertEquals(dto.embedded.marco, "ichi ni san");
assertEquals(dto.embedded.polo, 64L);
assertEquals(dto.embedded.alpha, Alpha.A);
}
@Test
public void testMap2DTOView() {
Map<String, Object> src = Collections.singletonMap("pong", 42);
MyDTOWithMethods dto = converter.convert(src).targetAs(MyDTO.class).to(MyDTOWithMethods.class);
assertEquals(42, dto.pong);
}
@Test @SuppressWarnings({ "rawtypes", "unchecked" })
public void testDTOWithGenerics() {
MyDTO2 dto = new MyDTO2();
dto.longList = Arrays.asList(999L, 1000L);
dto.dtoMap = new LinkedHashMap<>();
MyDTO3 subDTO1 = new MyDTO3();
subDTO1.charSet = new HashSet<>(Arrays.asList('f', 'o', 'o'));
dto.dtoMap.put("zzz", subDTO1);
MyDTO3 subDTO2 = new MyDTO3();
subDTO2.charSet = new HashSet<>(Arrays.asList('b', 'a', 'r'));
dto.dtoMap.put("aaa", subDTO2);
Map m = converter.convert(dto).to(Map.class);
assertEquals(2, m.size());
assertEquals(Arrays.asList(999L, 1000L), m.get("longList"));
Map nestedMap = (Map) m.get("dtoMap");
// Check iteration order is preserved by iterating
int i=0;
for (Iterator<Map.Entry> it = nestedMap.entrySet().iterator(); it.hasNext(); i++) {
Map.Entry entry = it.next();
switch (i) {
case 0:
assertEquals("zzz", entry.getKey());
MyDTO3 dto1 = (MyDTO3) entry.getValue();
assertNotSame("Should have created a copy", subDTO1, dto1);
assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), dto1.charSet);
break;
case 1:
assertEquals("aaa", entry.getKey());
MyDTO3 dto2 = (MyDTO3) entry.getValue();
assertNotSame("Should have created a copy", subDTO2, dto2);
assertEquals(new HashSet<Character>(Arrays.asList('b', 'a', 'r')), dto2.charSet);
break;
default:
fail("Unexpected number of elements on map");
}
}
// convert back
MyDTO2 dto2 = converter.convert(m).to(MyDTO2.class);
assertEquals(dto.longList, dto2.longList);
// Cannot simply do dto.equals() as the DTOs don't implement that
assertEquals(dto.dtoMap.size(), dto2.dtoMap.size());
MyDTO3 dto2SubZZZ = dto2.dtoMap.get("zzz");
assertEquals(dto2SubZZZ.charSet, new HashSet<Character>(Arrays.asList('f', 'o')));
MyDTO3 dto2SubAAA = dto2.dtoMap.get("aaa");
assertEquals(dto2SubAAA.charSet, new HashSet<Character>(Arrays.asList('b', 'a', 'r')));
}
@Test
public void testMapToDTOWithGenerics() {
Map<String, Object> dto = new HashMap<>();
dto.put("longList", Arrays.asList((short)999, "1000"));
Map<String, Object> dtoMap = new LinkedHashMap<>();
dto.put("dtoMap", dtoMap);
Map<String, Object> subDTO1 = new HashMap<>();
subDTO1.put("charSet", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));
dtoMap.put("zzz", subDTO1);
Map<String, Object> subDTO2 = new HashMap<>();
subDTO2.put("charSet", new HashSet<>(Arrays.asList('b', 'a', 'r')));
dtoMap.put("aaa", subDTO2);
MyDTO2 converted = converter.convert(dto).to(MyDTO2.class);
assertEquals(Arrays.asList(999L, 1000L), converted.longList);
Map<String, MyDTO3> nestedMap = converted.dtoMap;
// Check iteration order is preserved by iterating
int i=0;
for (Iterator<Map.Entry<String, MyDTO3>> it = nestedMap.entrySet().iterator(); it.hasNext(); i++) {
Map.Entry<String, MyDTO3> entry = it.next();
switch (i) {
case 0:
assertEquals("zzz", entry.getKey());
MyDTO3 dto1 = entry.getValue();
assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), dto1.charSet);
break;
case 1:
assertEquals("aaa", entry.getKey());
MyDTO3 dto2 = entry.getValue();
assertEquals(new HashSet<Character>(Arrays.asList('b', 'a', 'r')), dto2.charSet);
break;
default:
fail("Unexpected number of elements on map");
}
}
}
@Test
public void testMapToDTOWithGenericVariables() {
Map<String, Object> dto = new HashMap<>();
dto.put("set", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));
dto.put("raw", "1234");
dto.put("array", Arrays.asList("foo", (int) 'o', 'o'));
MyGenericDTOWithVariables<Character> converted =
converter.convert(dto).to(new TypeReference<MyGenericDTOWithVariables<Character>>() {});
assertEquals(Character.valueOf('1'), converted.raw);
assertArrayEquals(new Character[] {'f', 'o', 'o'}, converted.array);
assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), converted.set);
}
@Test
public void testMapToDTOWithSurplusMapFiels() {
Map<String, String> m = new HashMap<>();
m.put("foo", "bar");
MyDTO3 dtoDoesNotMap = converter.convert(m).to(MyDTO3.class);
assertNull(dtoDoesNotMap.charSet);
}
@Test @SuppressWarnings("rawtypes")
public void testCopyMap() {
Map m = new HashMap();
Map m2 = converter.convert(m).to(Map.class);
assertEquals(m, m2);
assertNotSame(m, m2);
}
@Test @SuppressWarnings({ "rawtypes", "unchecked" })
public void testCopyMap2() {
Map m = new HashMap();
m.put("key", Arrays.asList("a", "b", "c"));
Map m2 = converter.convert(m).to(Map.class);
assertEquals(m, m2);
assertNotSame(m, m2);
}
@Test
public void testConversionPriority() {
MyBean mb = new MyBean();
mb.intfVal = 17;
mb.beanVal = "Hello";
assertEquals(Collections.singletonMap("value", "Hello"),
converter.convert(mb).sourceAsBean().to(Map.class));
}
@Test
public void testConvertAsInterface() {
MyBean mb = new MyBean();
mb.intfVal = 17;
mb.beanVal = "Hello";
assertEquals(17,
converter.convert(mb).sourceAs(MyIntf.class).to(Map.class).get("value"));
}
@Test
public void testConvertAsBean() {
MyBean mb = new MyBean();
mb.intfVal = 17;
mb.beanVal = "Hello";
assertEquals(Collections.singletonMap("value", "Hello"),
converter.convert(mb).sourceAsBean().to(Map.class));
}
@Test
public void testConvertAsDTO() {
MyClass3 mc3 = new MyClass3(17);
assertEquals(17,
converter.convert(mc3).sourceAsDTO().to(Map.class).get("value"));
}
@Test
public void testDTONameMangling() {
Map<String,String> m = new HashMap<>();
m.put("org.osgi.framework.uuid", "test123");
m.put("myProperty143", "true");
m.put("my$prop", "42");
m.put("dot.prop", "456");
m.put(".secret", " ");
m.put("another_prop", "lalala");
m.put("three_.prop", "hi ha ho");
m.put("four._prop", "");
m.put("five..prop", "test");
m.put("six-prop", "987");
m.put("seven$.prop", "3.141");
MyDTO7 dto = converter.convert(m).to(MyDTO7.class);
assertEquals("test123", dto.org_osgi_framework_uuid);
assertTrue(dto.myProperty143);
assertEquals(42, dto.my$$prop);
assertEquals(Long.valueOf(456L), dto.dot_prop);
assertEquals(' ', dto._secret);
assertEquals("lalala", dto.another__prop);
assertEquals("hi ha ho", dto.three___prop);
assertEquals("", dto.four_$__prop);
assertEquals("test", dto.five_$_prop);
assertEquals((short) 987, dto.six$_$prop);
dto.seven$$_$prop = 3.141;
// And convert back
Map<String, String> m2 = converter.convert(dto).to(new TypeReference<Map<String,String>>() {});
assertEquals(new HashMap<String,String>(m), new HashMap<String,String>(m2));
}
@Test
public void testCollectionInterfaceMapping() {
Collection<?> coll = converter.convert("test").to(Collection.class);
assertEquals("test", coll.iterator().next());
List<?> list = converter.convert("test").to(List.class);
assertEquals("test", list.iterator().next());
Set<?> set = converter.convert("test").to(Set.class);
assertEquals("test", set.iterator().next());
NavigableSet<?> ns = converter.convert("test").to(NavigableSet.class);
assertEquals("test", ns.iterator().next());
SortedSet<?> ss = converter.convert("test").to(SortedSet.class);
assertEquals("test", ss.iterator().next());
Queue<?> q = converter.convert("test").to(Queue.class);
assertEquals("test", q.iterator().next());
Deque<?> dq = converter.convert("test").to(Deque.class);
assertEquals("test", dq.iterator().next());
Map<?,?> m = converter.convert(Collections.singletonMap("x", "y")).to(Map.class);
assertEquals("y", m.get("x"));
ConcurrentMap<?,?> cm = converter.convert(Collections.singletonMap("x", "y")).to(ConcurrentMap.class);
assertEquals("y", cm.get("x"));
ConcurrentNavigableMap<?,?> cnm = converter.convert(Collections.singletonMap("x", "y")).to(ConcurrentNavigableMap.class);
assertEquals("y", cnm.get("x"));
NavigableMap<?,?> nm = converter.convert(Collections.singletonMap("x", "y")).to(NavigableMap.class);
assertEquals("y", nm.get("x"));
SortedMap<?,?> sm = converter.convert(Collections.singletonMap("x", "y")).to(SortedMap.class);
assertEquals("y", sm.get("x"));
}
@SuppressWarnings("unchecked")
@Test
public void testLiveMapFromInterface() {
int[] val = new int[1];
val[0] = 51;
MyIntf intf = new MyIntf() {
@Override
public int value() {
return val[0];
}
};
@SuppressWarnings("rawtypes")
Map m = converter.convert(intf).view().to(Map.class);
assertEquals(51, m.get("value"));
val[0] = 52;
assertEquals("Changes to the backing map should be reflected",
52, m.get("value"));
m.put("value", 53);
assertEquals(53, m.get("value"));
val[0] = 54;
assertEquals("Changes to the backing map should not be reflected any more",
53, m.get("value"));
}
@SuppressWarnings("unchecked")
@Test
public void testLiveMapFromDTO() {
MyDTO8 myDTO = new MyDTO8();
myDTO.count = MyDTO8.Count.TWO;
myDTO.pong = 42L;
@SuppressWarnings("rawtypes")
Map m = converter.convert(myDTO).view().to(Map.class);
assertEquals(42L, m.get("pong"));
myDTO.ping = "Ping!";
assertEquals("Ping!", m.get("ping"));
myDTO.pong = 52L;
assertEquals(52L, m.get("pong"));
myDTO.ping = "Pong!";
assertEquals("Pong!", m.get("ping"));
assertNull(m.get("nonexistant"));
m.put("pong", 62L);
myDTO.ping = "Poing!";
myDTO.pong = 72L;
assertEquals("Pong!", m.get("ping"));
assertEquals(62L, m.get("pong"));
assertNull(m.get("nonexistant"));
}
@Test
public void testMapFromDTO() {
MyDTO9 dto = new MyDTO9();
dto.key1 = "value1";
dto.key2 = "value2";
Map<Character, Character> m = converter.convert(dto).to(new TypeReference<Map<Character, Character>>() {});
assertEquals(1, m.size());
assertEquals('v', (char) m.get('k'));
assertTrue(m.containsKey('k'));
assertFalse(m.containsKey("key1"));
assertTrue(m.containsValue('v'));
assertFalse(m.containsValue("value1"));
}
@Test
public void testLiveMapFromDictionary() throws URISyntaxException {
URI testURI = new URI("http://foo");
Hashtable<String, Object> d = new Hashtable<>();
d.put("test", testURI);
Map<String, Object> m = converter.convert(d).view().to(new TypeReference<Map<String, Object>>(){});
assertEquals(testURI, m.get("test"));
URI testURI2 = new URI("http://bar");
d.put("test2", testURI2);
assertEquals(testURI2, m.get("test2"));
assertEquals(testURI, m.get("test"));
}
@Test
public void testLiveMapFromMap() {
Map<String, String> s = new HashMap<>();
s.put("true", "123");
s.put("false", "456");
Map<Boolean, Short> m = converter.convert(s).view().to(new TypeReference<Map<Boolean, Short>>(){});
assertEquals(Short.valueOf("123"), m.get(Boolean.TRUE));
assertEquals(Short.valueOf("456"), m.get(Boolean.FALSE));
s.remove("true");
assertNull(m.get(Boolean.TRUE));
s.put("TRUE", "999");
assertEquals(Short.valueOf("999"), m.get(Boolean.TRUE));
}
@Test
public void testLiveMapFromBean() {
MyBean mb = new MyBean();
mb.beanVal = "" + Long.MAX_VALUE;
Map<SomeEnum, Long> m = converter.convert(mb).sourceAsBean().view().to(new TypeReference<Map<SomeEnum, Long>>(){});
assertEquals(1, m.size());
assertEquals(Long.valueOf(Long.MAX_VALUE), m.get(SomeEnum.VALUE));
mb.beanVal = "" + Long.MIN_VALUE;
assertEquals(Long.valueOf(Long.MIN_VALUE), m.get(SomeEnum.VALUE));
m.put(SomeEnum.GETVALUE, 123L);
mb.beanVal = "12";
assertEquals(Long.valueOf(Long.MIN_VALUE), m.get(SomeEnum.VALUE));
}
@Test
public void testPrefixDTO() {
Map<String, String> m = new HashMap<>();
m.put("org.foo.bar.width", "327");
m.put("org.foo.bar.warp", "eeej");
m.put("length", "12");
PrefixDTO dto = converter.convert(m).to(PrefixDTO.class);
assertEquals(327L, dto.width);
assertEquals("This one should not be set", 0, dto.length);
Map<String, String> m2 = converter.convert(dto).to(new TypeReference<HashMap<String,String>>() {});
Map<String, String> expected = new HashMap<>();
expected.put("org.foo.bar.width", "327");
expected.put("org.foo.bar.length", "0");
assertEquals(expected, m2);
}
@Test
public void testPrefixInterface() {
Map<String, String> m = new HashMap<>();
m.put("org.foo.bar.width", "327");
m.put("org.foo.bar.warp", "eeej");
m.put("length", "12");
PrefixInterface i = converter.convert(m).to(PrefixInterface.class);
assertEquals(327L, i.width());
try {
i.length();
fail("Should have thrown an exception");
} catch (ConversionException ce) {
// good
}
PrefixInterface i2 = new PrefixInterface() {
@Override
public long width() {
return Long.MAX_VALUE;
}
@Override
public int length() {
return Integer.MIN_VALUE;
}
};
Map<String, String> m2 = converter.convert(i2).to(new TypeReference<Map<String,String>>() {});
Map<String, String> expected = new HashMap<>();
expected.put("org.foo.bar.width", "" + Long.MAX_VALUE);
expected.put("org.foo.bar.length", "" + Integer.MIN_VALUE);
assertEquals(expected, m2);
}
@Test
public void testAnnotationInterface() {
Map<String, String> m = new HashMap<>();
m.put("org.foo.bar.width", "327");
m.put("org.foo.bar.warp", "eeej");
m.put("length", "12");
PrefixAnnotation pa = converter.convert(m).to(PrefixAnnotation.class);
assertEquals(327L, pa.width());
assertEquals(51, pa.length());
Map<String, String> m2 = converter.convert(pa).to(new TypeReference<Map<String,String>>() {});
Map<String, String> expected = new HashMap<>();
expected.put("org.foo.bar.width", "327");
expected.put("org.foo.bar.length", "51");
assertEquals(expected, m2);
}
@Test
public void testPrefixEnumAnnotation() {
PrefixEnumAnnotation pea = converter.convert(Collections.emptyMap()).to(PrefixEnumAnnotation.class);
assertEquals(1000, pea.timeout());
assertEquals(PrefixEnumAnnotation.Type.SINGLE, pea.type());
@SuppressWarnings("rawtypes")
Map m = converter.convert(pea).to(Map.class);
assertEquals(1000L, m.get("com.acme.config.timeout"));
assertEquals(PrefixEnumAnnotation.Type.SINGLE, m.get("com.acme.config.type"));
}
@Test
public void testTargetAsString() {
Map<String, String> m = new HashMap<>();
CharSequence cs = converter.convert(m).targetAs(String.class).to(CharSequence.class);
assertNull(cs);
Map<String, String> m2 = new HashMap<>();
m2.put("Hi", "there");
CharSequence cs2 = converter.convert(m2).targetAs(String.class).to(CharSequence.class);
assertEquals("Hi", cs2);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testTargetAsDTO() {
MyDTOWithMethods expected = new MyDTOWithMethods();
expected.count = Count.ONE;
expected.ping = "pong";
expected.pong = 42;
Map m = new HashMap<>();
m.put("count", Count.ONE);
m.put("ping", "pong");
m.put("pong", 42);
MyDTOWithMethods actual = converter.convert(m).targetAsDTO().to(MyDTOWithMethods.class);
assertEquals(expected.count, actual.count);
assertEquals(expected.ping, actual.ping);
assertEquals(expected.pong, actual.pong);
}
@SuppressWarnings("rawtypes")
@Test
public void testLongArrayToLongCollection() {
Long[] la = new Long[] {Long.MIN_VALUE, Long.MAX_VALUE};
List lc = converter.convert(la).to(List.class);
assertEquals(la.length, lc.size());
int i=0;
for (Iterator it = lc.iterator(); it.hasNext(); i++) {
assertEquals(la[i], it.next());
}
}
@Test
public void testMapToInterfaceWithGenerics() {
Map<String, Object> dto = new HashMap<>();
dto.put("charSet", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));
MyGenericInterface converted = converter.convert(dto).to(MyGenericInterface.class);
assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), converted.charSet());
}
@Test
public void testMapToInterfaceWithGenericVariables() {
Map<String, Object> dto = new HashMap<>();
dto.put("set", new HashSet<>(Arrays.asList("foo", (int) 'o', 'o')));
dto.put("raw", "1234");
dto.put("array", Arrays.asList("foo", (int) 'o', 'o'));
MyGenericInterfaceWithVariables<Character> converted =
converter.convert(dto).to(new TypeReference<MyGenericInterfaceWithVariables<Character>>() {});
assertEquals(Character.valueOf('1'), converted.raw());
assertArrayEquals(new Character[] {'f', 'o', 'o'}, converted.array());
assertEquals(new HashSet<Character>(Arrays.asList('f', 'o')), converted.set());
}
@Test
public void testMapToInterfaceWithOptionalValue() throws Exception {
ConverterBuilder cb = Converters.newConverterBuilder();
cb.errorHandler(new ConverterFunction() {
@Override
public Object apply(Object pObj, Type pTargetType) throws Exception {
if ("java.lang.Integer".equals(pTargetType.getTypeName()))
{
return 0;
}
return ConverterFunction.CANNOT_HANDLE;
}
});
Converter convWithErrorHandler = cb.build();
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", "harley");
MyIntf2 inter = convWithErrorHandler.convert(map).to(MyIntf2.class);
assertEquals("harley", inter.code());
assertEquals(Integer.valueOf(0), inter.value());
}
static interface MyIntf2 {
String code();
Integer value();
}
static class MyClass2 {
private final String value;
public MyClass2(String v) {
value = v;
}
@Override
public String toString() {
return value;
}
}
static interface MyIntf {
int value();
}
static class MyBean implements MyIntf {
int intfVal;
String beanVal;
@Override
public int value() {
return intfVal;
}
public String getValue() {
return beanVal;
}
}
static class MyClass3 {
public int value;
public String string = "String";
public MyClass3( int value ) {
this.value = value;
}
public int value() {
return value;
}
}
static @interface MyAnnotation {
int value() default 17;
}
enum SomeEnum { VALUE, GETVALUE };
}