
com.amazonaws.services.dynamodbv2.document.Item Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk-osgi Show documentation
Show all versions of aws-java-sdk-osgi Show documentation
The AWS SDK for Java with support for OSGi. The AWS SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).
/*
* Copyright 2014-2016 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.document;
import static com.amazonaws.services.dynamodbv2.document.internal.InternalUtils.checkInvalidAttrName;
import static com.amazonaws.services.dynamodbv2.document.internal.InternalUtils.checkInvalidAttribute;
import static com.amazonaws.services.dynamodbv2.document.internal.InternalUtils.rejectNullInput;
import static com.amazonaws.services.dynamodbv2.document.internal.InternalUtils.rejectNullOrEmptyInput;
import static com.amazonaws.services.dynamodbv2.document.internal.InternalUtils.rejectNullValue;
import static com.amazonaws.services.dynamodbv2.document.internal.InternalUtils.valToString;
import static com.amazonaws.util.BinaryUtils.copyAllBytesFrom;
import static com.amazonaws.util.BinaryUtils.copyBytesFrom;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.amazonaws.services.dynamodbv2.document.internal.InternalUtils;
import com.amazonaws.services.dynamodbv2.document.internal.ItemValueConformer;
import com.amazonaws.util.Base64;
import com.amazonaws.util.json.Jackson;
/**
* An item in DynamoDB. An item is a collection of attributes. Each attribute
* has a name and a value. An attribute value can be one of the followings:
*
* - String
* - Set<String>
* - Number (including any subtypes and primitive types)
* - Set<Number>
* - byte[]
* - Set<byte[]>
* - ByteBuffer
* - Set<ByteBuffer>
* - Boolean or boolean
* - null
* - Map<String,T>, where T can be any type on this list but must not
* induce any circular reference
* - List<T>, where T can be any type on this list but must not induce
* any circular reference
*
* For an Item
to be successfully persisted in DynamoDB, at a
* minimum the respective attributes for the primary key must be specified.
*/
public class Item {
private static final String DUPLICATE_VALUES_FOUND_IN_INPUT = "Duplicate values found in input";
private final Map attributes = new LinkedHashMap();
private static final ItemValueConformer valueConformer = new ItemValueConformer();
/**
* Returns true if the specified attribute exists with a null value; false
* otherwise.
*/
public boolean isNull(String attrName) {
return attributes.containsKey(attrName)
&& attributes.get(attrName) == null;
}
/**
* Returns true if this item contains the specified attribute; false
* otherwise.
*/
public boolean isPresent(String attrName) {
return attributes.containsKey(attrName);
}
/**
* Returns the value of the specified attribute in the current item as a
* string; or null if the attribute either doesn't exist or the attribute
* value is null.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public String getString(String attrName) {
Object val = attributes.get(attrName);
return valToString(val);
}
/**
* Sets the value of the specified attribute in the current item to the
* given string value.
*/
public Item withString(String attrName, String val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, val);
return this;
}
/**
* Returns the value of the specified attribute in the current item as a
* BigDecimal
; or null if the attribute either doesn't exist or
* the attribute value is null.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*
* @throws NumberFormatException if the attribute value is not a valid
* representation of a {@code BigDecimal}.
*/
public BigDecimal getNumber(String attrName) {
Object val = attributes.get(attrName);
return toBigDecimal(val);
}
private BigDecimal toBigDecimal(Object val) {
if (val == null)
return null;
return val instanceof BigDecimal
? (BigDecimal) val
: new BigDecimal(val.toString())
;
}
/**
* Returns the value of the specified attribute in the current item as an
* BigInteger
; or null if the attribute doesn't exist.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*
* @throws NumberFormatException
* if the attribute value is null or not a valid representation
* of a {@code BigDecimal}.
*/
public BigInteger getBigInteger(String attrName) {
BigDecimal bd = getNumber(attrName);
return bd == null ? null : bd.toBigInteger();
}
/**
* Returns the value of the specified attribute in the current item as a
* short
.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*
* @throws NumberFormatException
* if the attribute value is null or not a valid representation
* of a {@code BigDecimal}.
*/
public short getShort(String attrName) {
BigDecimal bd = getNumber(attrName);
if (bd == null)
throw new NumberFormatException
("value of " + attrName + " is null");
return bd.shortValue();
}
/**
* Returns the value of the specified attribute in the current item as an
* int
.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*
* @throws NumberFormatException
* if the attribute value is null or not a valid representation
* of a {@code BigDecimal}.
*/
public int getInt(String attrName) {
BigDecimal bd = getNumber(attrName);
if (bd == null)
throw new NumberFormatException
("value of " + attrName + " is null");
return bd.intValue();
}
/**
* Returns the value of the specified attribute in the current item as an
* long
.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*
* @throws NumberFormatException
* if the attribute value is null or not a valid representation
* of a {@code BigDecimal}.
*/
public long getLong(String attrName) {
BigDecimal bd = getNumber(attrName);
if (bd == null)
throw new NumberFormatException
("value of " + attrName + " is null");
return bd.longValue();
}
/**
* Returns the value of the specified attribute in the current item as a
* float
.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*
* @throws NumberFormatException
* if the attribute value is null or not a valid representation
* of a {@code BigDecimal}.
*/
public float getFloat(String attrName) {
BigDecimal bd = getNumber(attrName);
if (bd == null)
throw new NumberFormatException
("value of " + attrName + " is null");
return bd.floatValue();
}
/**
* Returns the value of the specified attribute in the current item as a
* double
.
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*
* @throws NumberFormatException
* if the attribute value is null or not a valid representation
* of a {@code BigDecimal}.
*/
public double getDouble(String attrName) {
BigDecimal bd = getNumber(attrName);
if (bd == null)
throw new NumberFormatException
("value of " + attrName + " is null");
return bd.doubleValue();
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withNumber(String attrName, BigDecimal val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, val);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withNumber(String attrName, Number val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, toBigDecimal(val));
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withInt(String attrName, int val) {
checkInvalidAttrName(attrName);
return withNumber(attrName, Integer.valueOf(val));
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBigInteger(String attrName, BigInteger val) {
checkInvalidAttrName(attrName);
return withNumber(attrName, val);
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withShort(String attrName, short val) {
checkInvalidAttrName(attrName);
return withNumber(attrName, Short.valueOf(val));
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withFloat(String attrName, float val) {
checkInvalidAttrName(attrName);
return withNumber(attrName, Float.valueOf(val));
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withDouble(String attrName, double val) {
checkInvalidAttrName(attrName);
return withNumber(attrName, Double.valueOf(val));
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withLong(String attrName, long val) {
checkInvalidAttrName(attrName);
return withNumber(attrName, Long.valueOf(val));
}
/**
* Returns the value of the specified attribute in the current item as a
* byte array; or null if the attribute either doesn't exist or the
* attribute value is null.
*
* @throws UnsupportedOperationException
* If the attribute value involves a byte buffer which is not
* backed by an accessible array
*
* @throws IncompatibleTypeException
* if the attribute value cannot be converted into a byte array
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public byte[] getBinary(String attrName) {
Object val = attributes.get(attrName);
return toByteArray(val);
}
/**
* Returns the value of the specified attribute in the current item as a
* ByteBuffer
; or null if the attribute either doesn't exist or
* the attribute value is null.
*
* @throws IncompatibleTypeException
* if the attribute value cannot be converted into a byte array
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public ByteBuffer getByteBuffer(String attrName) {
Object val = attributes.get(attrName);
return toByteBuffer(val);
}
/**
* This method is assumed to be only called from a getter method, but NOT
* from a setter method.
*/
private byte[] toByteArray(Object val) {
if (val == null)
return null;
if (val instanceof byte[])
return (byte[]) val;
if (val instanceof ByteBuffer) {
// Defensive code but execution should never get here. The internal
// representation of binary should always be
// byte[], not ByteBuffer. This allows Item to be converted into
// a JSON string via Jackson without causing trouble.
return copyAllBytesFrom((ByteBuffer)val);
}
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a byte array");
}
private ByteBuffer toByteBuffer(Object val) {
if (val == null)
return null;
if (val instanceof byte[])
return ByteBuffer.wrap((byte[])val);
if (val instanceof ByteBuffer) {
// Defensive code but execution should never get here. The internal
// representation of binary should always be
// byte[], not ByteBuffer. This allows Item to be converted into
// a JSON string via Jackson without causing trouble.
return (ByteBuffer)val;
}
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a ByteBuffer");
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBinary(String attrName, byte[] val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, val);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBinary(String attrName, ByteBuffer val) {
checkInvalidAttribute(attrName, val);
// convert ByteBuffer to bytes to keep Jackson happy
attributes.put(attrName, copyBytesFrom(val));
return this;
}
/**
* Returns the value of the specified attribute in the current item as a set
* of strings; or null if the attribute either doesn't exist or the
* attribute value is null.
*
* @throws IncompatibleTypeException
* if the attribute value cannot be converted into a set of
* strings because of duplicate elements
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public Set getStringSet(String attrName) {
Object val = attributes.get(attrName);
if (val == null)
return null;
Set stringSet = new LinkedHashSet();
if (val instanceof Collection) {
Collection> col = (Collection>) val;
if (col.size() == 0)
return stringSet;
for (Object element: col) {
String s = element == null ? null : valToString(element);
if (!stringSet.add(s))
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a set of strings because of duplicate elements");
}
return stringSet;
}
stringSet.add(valToString(val));
return stringSet;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withStringSet(String attrName, Set val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, val);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withStringSet(String attrName, String ...val) {
checkInvalidAttribute(attrName, val);
Set strSet = new LinkedHashSet(Arrays.asList(val));
if (strSet.size() != val.length)
throw new IllegalArgumentException(DUPLICATE_VALUES_FOUND_IN_INPUT);
attributes.put(attrName, strSet);
return this;
}
/**
* Returns the value of the specified attribute in the current item as a set
* of BigDecimal's; or null if the attribute either doesn't exist or the
* attribute value is null.
*
* @throws NumberFormatException
* if the attribute involves a value that is not a valid
* representation of a {@code BigDecimal}.
*
* @throws IncompatibleTypeException
* if the attribute value cannot be converted into a set of
* BigDecimal
's because of duplicate elements
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public Set getNumberSet(String attrName) {
Object val = attributes.get(attrName);
if (val == null)
return null;
Set numSet = new LinkedHashSet();
if (val instanceof Collection) {
Collection> col = (Collection>) val;
if (col.size() == 0)
return numSet;
for (Object element: col) {
BigDecimal bd = toBigDecimal(element);
if (!numSet.add(bd))
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a set of BigDecimal's because of duplicate elements");
}
return numSet;
} else if (val instanceof BigDecimal) {
numSet.add((BigDecimal)val);
return numSet;
} else {
numSet.add(new BigDecimal(val.toString()));
return numSet;
}
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBigDecimalSet(String attrName, Set val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, val);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBigDecimalSet(String attrName, BigDecimal ... vals) {
checkInvalidAttribute(attrName, vals);
Set set = new LinkedHashSet(Arrays.asList(vals));
if (set.size() != vals.length)
throw new IllegalArgumentException(DUPLICATE_VALUES_FOUND_IN_INPUT);
attributes.put(attrName, set);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withNumberSet(String attrName, Number ... vals) {
checkInvalidAttribute(attrName, vals);
Set set = InternalUtils.toBigDecimalSet(vals);
if (set.size() != vals.length)
throw new IllegalArgumentException(DUPLICATE_VALUES_FOUND_IN_INPUT);
return withBigDecimalSet(attrName, set);
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withNumberSet(String attrName, Set vals) {
checkInvalidAttribute(attrName, vals);
Set set = InternalUtils.toBigDecimalSet(vals);
if (set.size() != vals.size())
throw new IllegalArgumentException(DUPLICATE_VALUES_FOUND_IN_INPUT);
return withBigDecimalSet(attrName, set);
}
/**
* Returns the value of the specified attribute in the current item as a set
* of byte arrays; or null if the attribute either doesn't exist or the
* attribute value is null.
*
* @throws IncompatibleTypeException
* if the attribute value cannot be converted into a set of byte
* arrays
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public Set getBinarySet(String attrName) {
Object val = attributes.get(attrName);
if (val == null)
return null;
Set binarySet = new LinkedHashSet();
if (val instanceof Collection) {
Collection> col = (Collection>) val;
if (col.size() == 0)
return binarySet;
for (Object element: col) {
byte[] ba = toByteArray(element);
if (!binarySet.add(ba))
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a set of byte arrays because of duplicate elements");
}
return binarySet;
} else if (val instanceof byte[]) {
binarySet.add((byte[])val);
return binarySet;
} else if (val instanceof ByteBuffer) {
// Defensive code but execution should never get here. The internal
// representation of binary should always be
// byte[], not ByteBuffer. This allows Item to be converted into
// a JSON string via Jackson without causing trouble.
ByteBuffer bb = (ByteBuffer) val;
binarySet.add(copyAllBytesFrom(bb));
return binarySet;
}
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a set of byte arrays");
}
/**
* Returns the value of the specified attribute in the current item as a set
* of ByteBuffer
; or null if the attribute either doesn't exist
* or the attribute value is null.
*
* @throws IncompatibleTypeException
* if the attribute value cannot be converted into a set of
* ByteBuffer
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public Set getByteBufferSet(String attrName) {
Object val = attributes.get(attrName);
if (val == null)
return null;
Set binarySet = new LinkedHashSet();
if (val instanceof Collection) {
Collection> col = (Collection>) val;
if (col.size() == 0)
return binarySet;
for (Object element: col) {
ByteBuffer ba = toByteBuffer(element);
if (!binarySet.add(ba))
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a set of ByteBuffer because of duplicate elements");
}
return binarySet;
} else if (val instanceof ByteBuffer) {
// Defensive code but execution should never get here. The internal
// representation of binary should always be
// byte[], not ByteBuffer. This allows Item to be converted into
// a JSON string via Jackson without causing trouble.
binarySet.add((ByteBuffer)val);
return binarySet;
} else if (val instanceof byte[]) {
binarySet.add(ByteBuffer.wrap((byte[])val));
return binarySet;
}
throw new IncompatibleTypeException(val.getClass()
+ " cannot be converted into a set of ByteBuffer");
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBinarySet(String attrName, Set val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, val);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withByteBufferSet(String attrName, Set val) {
checkInvalidAttribute(attrName, val);
// convert ByteBuffer to bytes to keep Jackson happy
Set set = new LinkedHashSet(val.size());
for (ByteBuffer bb: val)
set.add(copyBytesFrom(bb));
attributes.put(attrName, set);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBinarySet(String attrName, byte[] ... vals) {
checkInvalidAttribute(attrName, vals);
Set set = new LinkedHashSet(Arrays.asList(vals));
if (set.size() != vals.length)
throw new IllegalArgumentException(DUPLICATE_VALUES_FOUND_IN_INPUT);
attributes.put(attrName, set);
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withBinarySet(String attrName, ByteBuffer ... vals) {
checkInvalidAttribute(attrName, vals);
// convert ByteBuffer to bytes to keep Jackson happy
Set set = new LinkedHashSet(vals.length);
for (ByteBuffer bb: vals)
set.add(copyBytesFrom(bb));
if (set.size() != vals.length)
throw new IllegalArgumentException(DUPLICATE_VALUES_FOUND_IN_INPUT);
attributes.put(attrName, set);
return this;
}
/**
* Returns the value of the specified attribute in the current item as a set
* of T
's.; or null if the attribute either doesn't exist or
* the attribute value is null.
*
* @throws ClassCastException
* if the attribute involves a value that cannot be casted to
* T
*
* @see #isNull(String) #isNull(String) to check if the attribute value is
* null.
* @see #isPresent(String) #isPresent(String) to check if the attribute
* value is present.
*/
public List getList(String attrName) {
Object val = attributes.get(attrName);
if (val == null)
return null;
if (val instanceof List) {
@SuppressWarnings("unchecked")
List ret = (List)val;
return ret;
}
List list = new ArrayList();
if (val instanceof Collection) {
Collection> col = (Collection>)val;
for (Object element: col) {
@SuppressWarnings("unchecked")
T t = (T)element;
list.add(t);
}
return list;
}
@SuppressWarnings("unchecked")
T t = (T)val;
list.add(t);
return list;
}
/**
* Sets the value of the specified attribute in the current item to the
* given value.
*/
public Item withList(String attrName, List> val) {
checkInvalidAttribute(attrName, val);
attributes.put(attrName, valueConformer.transform(val));
return this;
}
/**
* Sets the value of the specified attribute in the current item to the
* given values as a list.
*/
public Item withList(String attrName, Object ... vals) {
checkInvalidAttribute(attrName, vals);
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy