/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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.amazonaws.services.dynamodbv2.datamodeling;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Test;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.pojos.SubClass;
import com.amazonaws.services.dynamodbv2.pojos.TestClass;
import com.amazonaws.services.dynamodbv2.pojos.UnannotatedSubClass;
import com.amazonaws.services.s3.model.Region;
public class StandardModelFactoriesV2UnconvertTest {
protected static final DynamoDBMapperConfig CONFIG = new DynamoDBMapperConfig.Builder()
.withTypeConverterFactory(DynamoDBMapperConfig.DEFAULT.getTypeConverterFactory())
.withConversionSchema(ConversionSchemas.V2)
.build();
private static final DynamoDBMapperModelFactory factory = StandardModelFactories.of(new S3Link.Factory(new S3ClientCache((AWSCredentialsProvider)null)));
private static final DynamoDBMapperModelFactory.TableFactory models = factory.getTableFactory(CONFIG);
protected <T> Object unconvert(Class<T> clazz, Method getter, Method setter, AttributeValue value) {
final StandardAnnotationMaps.FieldMap<Object> map = StandardAnnotationMaps.of(getter, null);
return models.getTable(clazz).field(map.attributeName()).unconvert(value);
}
@Test
public void testBoolean() {
assertEquals(false, unconvert("getBoolean", "setBoolean",
new AttributeValue().withN("0")));
assertEquals(true, unconvert("getBoolean", "setBoolean",
new AttributeValue().withN("1")));
assertEquals(false, unconvert("getBoolean", "setBoolean",
new AttributeValue().withBOOL(false)));
assertEquals(true, unconvert("getBoolean", "setBoolean",
new AttributeValue().withBOOL(true)));
assertEquals(false, unconvert("getBoxedBoolean", "setBoxedBoolean",
new AttributeValue().withN("0")));
assertEquals(true, unconvert("getBoxedBoolean", "setBoxedBoolean",
new AttributeValue().withN("1")));
assertEquals(false, unconvert("getBoxedBoolean", "setBoxedBoolean",
new AttributeValue().withBOOL(false)));
assertEquals(true, unconvert("getBoxedBoolean", "setBoxedBoolean",
new AttributeValue().withBOOL(true)));
}
@Test
public void testString() {
assertEquals("test", unconvert("getString", "setString",
new AttributeValue("test")));
Assert.assertNull(unconvert("getCustomString", "setCustomString",
new AttributeValue("ignoreme")));
}
@Test
public void testUuid() {
UUID uuid = UUID.randomUUID();
assertEquals(uuid, unconvert("getUuid", "setUuid",
new AttributeValue(uuid.toString())));
}
@Test
public void testDate() {
assertEquals(new Date(0), unconvert("getDate", "setDate",
new AttributeValue("1970-01-01T00:00:00.000Z")));
Calendar c = GregorianCalendar.getInstance();
c.setTimeInMillis(0);
assertEquals(c, unconvert("getCalendar", "setCalendar",
new AttributeValue("1970-01-01T00:00:00.000Z")));
}
@Test
public void testNumbers() {
assertEquals((byte) 1, unconvert("getByte", "setByte",
new AttributeValue().withN("1")));
assertEquals((byte) 1, unconvert("getBoxedByte", "setBoxedByte",
new AttributeValue().withN("1")));
assertEquals((short) 1, unconvert("getShort", "setShort",
new AttributeValue().withN("1")));
assertEquals((short) 1, unconvert("getBoxedShort", "setBoxedShort",
new AttributeValue().withN("1")));
assertEquals(1, unconvert("getInt", "setInt",
new AttributeValue().withN("1")));
assertEquals(1, unconvert("getBoxedInt", "setBoxedInt",
new AttributeValue().withN("1")));
assertEquals(1l, unconvert("getLong", "setLong",
new AttributeValue().withN("1")));
assertEquals(1l, unconvert("getBoxedLong", "setBoxedLong",
new AttributeValue().withN("1")));
assertEquals(BigInteger.ONE, unconvert("getBigInt", "setBigInt",
new AttributeValue().withN("1")));
assertEquals(1.5f, unconvert("getFloat", "setFloat",
new AttributeValue().withN("1.5")));
assertEquals(1.5f, unconvert("getBoxedFloat", "setBoxedFloat",
new AttributeValue().withN("1.5")));
assertEquals(1.5d, unconvert("getDouble", "setDouble",
new AttributeValue().withN("1.5")));
assertEquals(1.5d, unconvert("getBoxedDouble", "setBoxedDouble",
new AttributeValue().withN("1.5")));
assertEquals(BigDecimal.ONE, unconvert("getBigDecimal", "setBigDecimal",
new AttributeValue().withN("1")));
}
@Test
public void testBinary() {
ByteBuffer test = ByteBuffer.wrap("test".getBytes());
Assert.assertTrue(Arrays.equals("test".getBytes(), (byte[]) unconvert(
"getByteArray", "setByteArray",
new AttributeValue().withB(test.slice()))));
assertEquals(test.slice(), unconvert("getByteBuffer", "setByteBuffer",
new AttributeValue().withB(test.slice())));
}
@Test
public void testBooleanSet() {
assertEquals(new HashSet<Boolean>() {{ add(true); }},
unconvert("getBooleanSet", "setBooleanSet",
new AttributeValue().withNS("1")));
assertEquals(new HashSet<Boolean>() {{ add(false); }},
unconvert("getBooleanSet", "setBooleanSet",
new AttributeValue().withNS("0")));
assertEquals(new HashSet<Boolean>() {{ add(true); add(false); }},
unconvert("getBooleanSet", "setBooleanSet",
new AttributeValue().withNS("0", "1")));
assertEquals(new HashSet<Boolean>() {{ add(true); }},
unconvert("getBooleanSet", "setBooleanSet",
new AttributeValue().withL(
new AttributeValue().withBOOL(true))));
assertEquals(new HashSet<Boolean>() {{ add(false); }},
unconvert("getBooleanSet", "setBooleanSet",
new AttributeValue().withL(
new AttributeValue().withBOOL(false))));
assertEquals(new HashSet<Boolean>() {{ add(false); add(true); }},
unconvert("getBooleanSet", "setBooleanSet",
new AttributeValue().withL(
new AttributeValue().withBOOL(false),
new AttributeValue().withBOOL(true))));
assertEquals(new HashSet<Boolean>() {{ add(null); }},
unconvert("getBooleanSet", "setBooleanSet",
new AttributeValue().withL(
new AttributeValue().withNULL(true))));
}
@Test
public void testStringSet() {
Assert.assertNull(unconvert("getStringSet", "setStringSet",
new AttributeValue().withNULL(true)));
assertEquals(new HashSet<String>() {{ add("a"); add("b"); }},
unconvert("getStringSet", "setStringSet",
new AttributeValue().withSS("a", "b")));
}
@Test
public void testUuidSet() {
Assert.assertNull(unconvert("getUuidSet", "setUuidSet",
new AttributeValue().withNULL(true)));
final UUID one = UUID.randomUUID();
final UUID two = UUID.randomUUID();
assertEquals(new HashSet<UUID>() {{ add(one); add(two); }},
unconvert("getUuidSet", "setUuidSet",
new AttributeValue().withSS(
one.toString(),
two.toString())));
}
@Test
public void testDateSet() {
assertEquals(Collections.singleton(new Date(0)),
unconvert("getDateSet", "setDateSet", new AttributeValue()
.withSS("1970-01-01T00:00:00.000Z")));
Calendar c = GregorianCalendar.getInstance();
c.setTimeInMillis(0);
assertEquals(Collections.singleton(c),
unconvert("getCalendarSet", "setCalendarSet",
new AttributeValue()
.withSS("1970-01-01T00:00:00.000Z")));
}
@Test
public void testNumberSet() {
Assert.assertNull(unconvert("getByteSet", "setByteSet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getShortSet", "setShortSet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getIntSet", "setIntSet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getLongSet", "setLongSet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getBigIntegerSet", "setBigIntegerSet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getFloatSet", "setFloatSet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getDoubleSet", "setDoubleSet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getBigDecimalSet", "setBigDecimalSet",
new AttributeValue().withNULL(true)));
assertEquals(new HashSet<Byte>() {{ add((byte) 1); }},
unconvert("getByteSet", "setByteSet",
new AttributeValue().withNS("1")));
assertEquals(new HashSet<Short>() {{ add((short) 1); }},
unconvert("getShortSet", "setShortSet",
new AttributeValue().withNS("1")));
assertEquals(new HashSet<Integer>() {{ add(1); }},
unconvert("getIntSet", "setIntSet",
new AttributeValue().withNS("1")));
assertEquals(new HashSet<Long>() {{ add(1l); }},
unconvert("getLongSet", "setLongSet",
new AttributeValue().withNS("1")));
assertEquals(new HashSet<BigInteger>() {{ add(BigInteger.ONE); }},
unconvert("getBigIntegerSet", "setBigIntegerSet",
new AttributeValue().withNS("1")));
assertEquals(new HashSet<Float>() {{ add(1.5f); }},
unconvert("getFloatSet", "setFloatSet",
new AttributeValue().withNS("1.5")));
assertEquals(new HashSet<Double>() {{ add(1.5d); }},
unconvert("getDoubleSet", "setDoubleSet",
new AttributeValue().withNS("1.5")));
assertEquals(new HashSet<BigDecimal>() {{ add(BigDecimal.ONE); }},
unconvert("getBigDecimalSet", "setBigDecimalSet",
new AttributeValue().withNS("1")));
}
@Test
public void testBinarySet() {
Assert.assertNull(unconvert("getByteArraySet", "setByteArraySet",
new AttributeValue().withNULL(true)));
Assert.assertNull(unconvert("getByteBufferSet", "setByteBufferSet",
new AttributeValue().withNULL(true)));
ByteBuffer test = ByteBuffer.wrap("test".getBytes());
Set<byte[]> result = (Set<byte[]>) unconvert(
"getByteArraySet", "setByteArraySet",
new AttributeValue().withBS(test.slice()));
assertEquals(1, result.size());
Assert.assertTrue(Arrays.equals(
"test".getBytes(),
result.iterator().next()));
Assert.assertEquals(Collections.singleton(test.slice()),
unconvert("getByteBufferSet", "setByteBufferSet",
new AttributeValue().withBS(test.slice())));
}
@Test
public void testObjectSet() {
Object result = unconvert("getObjectSet", "setObjectSet",
new AttributeValue().withL(new AttributeValue().withM(
new HashMap<String, AttributeValue>() {{
put("name", new AttributeValue("name"));
put("value", new AttributeValue().withN("123"));
put("null", new AttributeValue().withNULL(true));
}}
)));
assertEquals(Collections.singleton(new SubClass()), result);
result = unconvert("getObjectSet", "setObjectSet",
new AttributeValue().withL(
new AttributeValue().withNULL(true)));
assertEquals(Collections.<SubClass>singleton(null), result);
}
@Test
public void testList() {
Assert.assertNull(unconvert("getList", "setList",
new AttributeValue().withNULL(true)));
assertEquals(Arrays.asList("a", "b", "c"),
unconvert("getList", "setList", new AttributeValue().withL(
new AttributeValue("a"),
new AttributeValue("b"),
new AttributeValue("c"))));
assertEquals(Arrays.asList("a", null),
unconvert("getList", "setList", new AttributeValue().withL(
new AttributeValue("a"),
new AttributeValue().withNULL(true))));
}
@Test
public void testObjectList() {
Assert.assertNull(unconvert("getObjectList", "setObjectList",
new AttributeValue().withNULL(true)));
assertEquals(Arrays.asList(new SubClass(), null),
unconvert("getObjectList", "setObjectList",
new AttributeValue().withL(
new AttributeValue().withM(new HashMap<String, AttributeValue>() {{
put("name", new AttributeValue("name"));
put("value", new AttributeValue().withN("123"));
put("null", new AttributeValue().withNULL(true));
}}),
new AttributeValue().withNULL(true))));
}
@Test
public void testSetList() {
Assert.assertNull(unconvert("getSetList", "setSetList",
new AttributeValue().withNULL(true)));
assertEquals(Arrays.asList(new Set[] { null }),
unconvert("getSetList", "setSetList", new AttributeValue().withL(
new AttributeValue().withNULL(true))));
assertEquals(Arrays.asList(Collections.singleton("a")),
unconvert("getSetList", "setSetList", new AttributeValue().withL(
new AttributeValue().withSS("a"))));
}
@Test
public void testMap() {
Assert.assertNull(unconvert("getMap", "setMap",
new AttributeValue().withNULL(true)));
assertEquals(new HashMap<String, String>() {{
put("a", "b");
put("c", "d");
}},
unconvert("getMap", "setMap", new AttributeValue().withM(
new HashMap<String, AttributeValue>() {{
put("a", new AttributeValue("b"));
put("c", new AttributeValue("d"));
}})));
assertEquals(new HashMap<String, String>() {{
put("a", null);
}},
unconvert("getMap", "setMap", new AttributeValue().withM(
new HashMap<String, AttributeValue>() {{
put("a", new AttributeValue().withNULL(true));
}})));
}
@Test
public void testSetMap() {
Assert.assertNull(unconvert("getSetMap", "setSetMap",
new AttributeValue().withNULL(true)));
assertEquals(new HashMap<String, Set<String>>() {{
put("a", null);
put("b", new TreeSet<String>(Arrays.asList("a", "b")));
}},
unconvert("getSetMap", "setSetMap", new AttributeValue().withM(
new HashMap<String, AttributeValue>() {{
put("a", new AttributeValue().withNULL(true));
put("b", new AttributeValue().withSS("a", "b"));
}})));
}
@Test
public void testObject() {
Assert.assertNull(unconvert("getObject", "setObject",
new AttributeValue().withNULL(true)));
assertEquals(new SubClass(), unconvert("getObject", "setObject",
new AttributeValue().withM(new HashMap<String, AttributeValue>() {{
put("name", new AttributeValue("name"));
put("value", new AttributeValue().withN("123"));
}})));
assertEquals(new SubClass(), unconvert("getObject", "setObject",
new AttributeValue().withM(new HashMap<String, AttributeValue>() {{
put("name", new AttributeValue("name"));
put("value", new AttributeValue().withN("123"));
put("null", new AttributeValue().withNULL(true));
}})));
}
@Test
public void testUnannotatedObject() throws Exception {
Method getter = UnannotatedSubClass.class.getMethod("getChild");
Method setter = UnannotatedSubClass.class
.getMethod("setChild", UnannotatedSubClass.class);
try {
unconvert(UnannotatedSubClass.class, getter, setter, new AttributeValue().withS(""));
Assert.fail("Expected DynamoDBMappingException");
} catch (DynamoDBMappingException e) {
}
}
@Test
public void testS3Link() {
S3Link link = (S3Link) unconvert("getS3Link", "setS3Link",
new AttributeValue("{\"s3\":{"
+ "\"bucket\":\"bucket\","
+ "\"key\":\"key\","
+ "\"region\":null}}"));
assertEquals("bucket", link.getBucketName());
assertEquals("key", link.getKey());
assertEquals(Region.US_Standard, link.getS3Region());
}
public Object unconvert(String getter, String setter, AttributeValue value) {
try {
Method gm = TestClass.class.getMethod(getter);
Method sm = TestClass.class.getMethod(setter, gm.getReturnType());
return unconvert(TestClass.class, gm, sm, value);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException("BOOM", e);
}
}
}