
com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-java-sdk-dynamodb Show documentation
Show all versions of aws-java-sdk-dynamodb Show documentation
The AWS Java SDK for Amazon DynamoDB module holds the client classes that are used for communicating with Amazon DynamoDB Service
/*
* Copyright 2011-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.
* You may obtain a copy of the License at:
*
* http://aws.amazon.com/apache2.0
*
* 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 com.amazonaws.services.dynamodbv2.model.KeyType.HASH;
import static com.amazonaws.services.dynamodbv2.model.KeyType.RANGE;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig.SaveBehavior;
import com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters.Vector;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.Condition;
import com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ScalarAttributeType;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* Field model.
*
* @param The object type.
* @param The field model type.
*/
public class DynamoDBMapperFieldModel implements DynamoDBAutoGenerator, DynamoDBTypeConverter {
public static enum DynamoDBAttributeType { B, N, S, BS, NS, SS, BOOL, NULL, L, M; };
private final Id id;
private final Reflect reflect;
private final DynamoDBMapperValueConverter converter;
private final Properties properties;
@Deprecated
private ArgumentMarshaller argumentMarshaller;
private DynamoDBAttributeType dynamoDBAttributeType;
/**
* {@deprecated}
*/
@Deprecated
public DynamoDBMapperFieldModel(
String dynamoDBAttributeName,
DynamoDBAttributeType dynamoDBAttributeType,
ArgumentMarshaller argumentMarshaller) {
this.id = new Id((Class)Void.class, dynamoDBAttributeName);
this.properties = new Properties.Builder().withAttributeName(dynamoDBAttributeName);
this.reflect = null;
this.converter = null;
this.dynamoDBAttributeType = dynamoDBAttributeType;
this.argumentMarshaller = argumentMarshaller;
}
/**
* Creates a new field model instance.
* @param builder The builder.
*/
private DynamoDBMapperFieldModel(final Builder builder) {
this.id = builder.id;
this.properties = builder.properties;
this.reflect = builder.reflect;
this.converter = builder.converter;
}
/**
* Returns the name of the DynamoDB attribute this mapped field will be
* stored as.
*/
public String getDynamoDBAttributeName() {
return properties.attributeName();
}
/**
* Returns the type of the DynamoDB attribute this mapped field will be
* stored as.
*/
public DynamoDBAttributeType getDynamoDBAttributeType() {
return converter == null ? dynamoDBAttributeType : converter.getDynamoDBAttributeType();
}
/**
* (Internal usage only)
* Returns the argument marshaller that is bound to this mapped field.
*/
@Deprecated
ArgumentMarshaller getArgumentMarshaller() {
return argumentMarshaller;
}
/**
* Gets the ID.
* @return The ID.
*/
public final Id id() {
return id;
}
/**
* Gets the attribute name.
* @return The attribute name.
*/
public final String name() {
return properties.attributeName();
}
/**
* Gets the value from the object instance.
* @param object The object instance.
* @return The value.
*/
public final V get(final T object) {
try {
return reflect.get(object);
} catch (final RuntimeException e) {
throw new DynamoDBMappingException(id.format("could not get"), e);
}
}
/**
* Sets the value on the object instance.
* @param object The object instance.
* @param value The value.
*/
public final void set(final T object, final V value) {
try {
reflect.set(object, value);
} catch (final RuntimeException e) {
throw new DynamoDBMappingException(id.format("could not set"), e);
}
}
/**
* Determines if the mapping value can be auto-generated.
* @param object The object instance.
* @param saveBehavior The save behaviour.
* @param model The table model.
* @return True if can be auto-generated, false otherwise.
*/
public final boolean canGenerate(final T object, final SaveBehavior saveBehavior, final DynamoDBMapperTableModel model) {
if (getGenerateStrategy() == null) {
return false;
} else if (DynamoDBAutoGenerateStrategy.ALWAYS == getGenerateStrategy()) {
return true;
} else if (get(object) != null) {
return false;
} else if (anyKey()) {
return true;
} else if (saveBehavior == SaveBehavior.CLOBBER || saveBehavior == SaveBehavior.UPDATE) {
return true;
} else if (model != null && model.anyKeyGeneratable(object, saveBehavior)) {
return true;
} else {
return false;
}
}
/**
* Indicates if this attribute is a version attribute.
* @return True if it is, false otherwise.
*/
public final boolean versioned() {
if (properties.autoGenerator() != null) {
return properties.autoGenerator().getClass() == DynamoDBVersionAttribute.Generator.class;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public final DynamoDBAutoGenerateStrategy getGenerateStrategy() {
if (properties.autoGenerator() != null) {
return properties.autoGenerator().getGenerateStrategy();
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public final V generate(final V currentValue) {
try {
return properties.autoGenerator().generate(currentValue);
} catch (final RuntimeException e) {
throw new DynamoDBMappingException(id.format("could not generate"), e);
}
}
/**
* {@inheritDoc}
*/
@Override
public final AttributeValue convert(final V object) {
try {
return converter.convert(object);
} catch (final RuntimeException e) {
throw new DynamoDBMappingException(id.format("could not convert"), e);
}
}
/**
* {@inheritDoc}
*/
@Override
public final V unconvert(final AttributeValue object) {
try {
return converter.unconvert(object);
} catch (final RuntimeException e) {
throw new DynamoDBMappingException(id.format("could not unconvert"), e);
}
}
/**
* Gets the key type.
* @return The key type, or null if not a key.
*/
public final KeyType keyType() {
return properties.keyType();
}
/**
* Gets the global secondary indexes.
* @param keyType The key type.
* @return The list of global secondary indexes.
*/
public final List globalSecondaryIndexNames(final KeyType keyType) {
return properties.globalSecondaryIndexNames(keyType);
}
/**
* Gets the local secondary indexes.
* @return The list of local secondary indexes.
*/
public final List localSecondaryIndexNames() {
return properties.localSecondaryIndexNames();
}
/**
* Returns true if the field matches any key or index key.
* @param keyTypes The key types.
* @return True if matching any key type.
*/
public final boolean anyKey(KeyType ... keyTypes) {
for (final KeyType k : (keyTypes.length == 0 ? KeyType.values() : keyTypes)) {
if (keyType() == k) {
return true;
} else if (!globalSecondaryIndexNames(k).isEmpty()) {
return true;
} else if (RANGE == k && !localSecondaryIndexNames().isEmpty()) {
return true;
}
}
return false;
}
/**
* Gets the attribute deinition for this field.
* @return The attribute definition.
*/
public final AttributeDefinition definition() {
try {
return new AttributeDefinition(name(), ScalarAttributeType.valueOf(getDynamoDBAttributeType().name()));
} catch (final RuntimeException e) {
throw new DynamoDBMappingException(id.format("must be scalar (B, N, or S) but is " + getDynamoDBAttributeType()), e);
}
}
/**
* Get the current value from the object and generates a new value.
* @param object The object instance.
* @return The generated value.
*/
public final AttributeValue generateAndConvert(final T object) {
return convert(generate(get(object)));
}
/**
* Get the current value from the object and convert it.
* @param object The object instance.
* @return The converted value.
*/
public final AttributeValue getAndConvert(final T object) {
return convert(get(object));
}
/**
* Unconverts the value and sets it on the object.
* @param object The object instance.
* @param value The attribute value.
*/
public final void unconvertAndSet(final T object, final AttributeValue value) {
set(object, unconvert(value));
}
/**
* Converts the object values into {@code AttributeValue}s.
* @param values The object values.
* @return The attribute values.
*/
public final Collection convertAll(final Collection values) {
return Vector.convert(values, this);
}
/**
* Unconverts the {@code AttributeValue}s into the object value.
* @param values The attribute values.
* @return The field model values.
*/
public final Collection unconvertAll(final Collection values) {
return Vector.unconvert(values, this);
}
/**
* Creates an expectation that the value should exist.
* @param value The value.
* @return The expected value.
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression#withExpectedEntry
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDeleteExpression#withExpectedEntry
* @see com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue
*/
public final ExpectedAttributeValue expectedExists(final V value) {
return new ExpectedAttributeValue().withExists(true).withValue(convert(value));
}
/**
* Creates an expectation that the value should not exist.
* @return The expected value.
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression#withExpectedEntry
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDeleteExpression#withExpectedEntry
* @see com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue
*/
public final ExpectedAttributeValue expectedNotExists() {
return new ExpectedAttributeValue().withExists(false);
}
/**
* Creates an expectation that the value should exist if the value is not
* null or an expectation that the value should not exist otherwise.
* @param value The value.
* @return The expected value.
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression#withExpectedEntry
* @see com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDeleteExpression#withExpectedEntry
* @see com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue
*/
public final ExpectedAttributeValue expectedIfExists(final V value) {
return value == null ? expectedNotExists() : expectedExists(value);
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#BEGINS_WITH
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition beginsWith(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.BEGINS_WITH).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified values.
* @param lo The start of the range (inclusive).
* @param hi The end of the range (inclusive).
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#BETWEEN
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition between(final V lo, final V hi) {
return new Condition().withComparisonOperator(ComparisonOperator.BETWEEN).withAttributeValueList(convert(lo), convert(hi));
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#CONTAINS
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition contains(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.CONTAINS).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#EQ
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition eq(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.EQ).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#GE
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition ge(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.GE).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#GT
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition gt(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.GT).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified values.
* @param values The values.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#IN
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition in(final V ... values) {
return new Condition().withComparisonOperator(ComparisonOperator.IN).withAttributeValueList(convertAll(Arrays.asList(values)));
}
/**
* Creates a condition which filters on the specified values.
* @param values The values.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#IN
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition in(final Collection values) {
return new Condition().withComparisonOperator(ComparisonOperator.IN).withAttributeValueList(convertAll(values));
}
/**
* Creates a condition which filters on the specified value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#NULL
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition isNull() {
return new Condition().withComparisonOperator(ComparisonOperator.NULL);
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#LE
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition le(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.LE).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#LT
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition lt(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.LT).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#NE
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition ne(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.NE).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified value.
* @param value The value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#NOT_CONTAINS
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition notContains(final V value) {
return new Condition().withComparisonOperator(ComparisonOperator.NOT_CONTAINS).withAttributeValueList(convert(value));
}
/**
* Creates a condition which filters on the specified value.
* @return The condition.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#NOT_NULL
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition notNull() {
return new Condition().withComparisonOperator(ComparisonOperator.NOT_NULL);
}
/**
* Creates a condition which filters on any non-null argument; if {@code lo}
* is null a {@code LE} condition is applied on {@code hi}, if {@code hi}
* is null a {@code GE} condition is applied on {@code lo}.
* @param lo The start of the range (inclusive).
* @param hi The end of the range (inclusive).
* @return The condition or null if both arguments are null.
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#BETWEEN
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#EQ
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#GE
* @see com.amazonaws.services.dynamodbv2.model.ComparisonOperator#LE
* @see com.amazonaws.services.dynamodbv2.model.Condition
*/
public final Condition betweenAny(final V lo, final V hi) {
return lo == null ? (hi == null ? null : le(hi)) : (hi == null ? ge(lo) : (lo.equals(hi) ? eq(lo) : between(lo,hi)));
}
/**
* The field's "global" identifier.
*/
public static final class Id {
private final Class type;
private final String name;
/**
* Construts a new field identifier.
* @param type The object type.
* @param name The attribute name.
*/
public Id(final Class type, final String name) {
this.type = type;
this.name = name;
}
/**
* Gets the attribute name.
* @return The attribute name.
*/
public String name() {
return this.name;
}
/**
* {@inheritDoc}
*/
@Override
public final boolean equals(final Object o) {
return o instanceof Id && ((Id)o).type == type && ((Id)o).name.equals(name);
}
/**
* {@inheritDoc}
*/
@Override
public final int hashCode() {
return type.hashCode() ^ name.hashCode();
}
/**
* {@inheritDoc}
*/
@Override
public final String toString() {
return new StringBuilder().append(type.getName()).append("[").append(name).append("]").toString();
}
/**
* Formats an exception message with the identifier.
* @param message The exception message.
* @param args Optional formatting arguments.
* @return The formatted message.
*/
public final String format(String message, final Object ... args) {
if (message != null && args.length > 0) {
try {
message = String.format(message, args);
} catch (final RuntimeException no) {}
}
return new StringBuilder().append("Field ").append(this).append(" ").append(message).toString();
}
}
/**
* Get/set reflection operations.
* @param The object type.
* @param The value type.
*/
static interface Reflect {
public V get(T object);
public void set(T object, V value);
}
/**
* The field model properties.
*/
static interface Properties {
public Class targetType();
public String attributeName();
public KeyType keyType();
public List globalSecondaryIndexNames(KeyType keyType);
public List localSecondaryIndexNames();
public DynamoDBAutoGenerator autoGenerator();
/**
* Properties builder.
*/
static final class Builder implements Properties {
private Map> gsis = Collections.emptyMap();
private List lsis = Collections.emptyList();
private DynamoDBAutoGenerator autoGenerator;
private String attributeName;
private Class targetType;
private KeyType keyType;
/**
* Populates the builder properties with the specified defaults.
* @param defaults The default properties.
* @return This builder instance for chaining.
*/
public Builder with(final Properties defaults) {
this.targetType = defaults.targetType();
this.attributeName = defaults.attributeName();
this.keyType = defaults.keyType();
this.autoGenerator = defaults.autoGenerator();
this.lsis = defaults.localSecondaryIndexNames();
for (final KeyType keyType : KeyType.values()) {
final List names = defaults.globalSecondaryIndexNames(keyType);
if (!names.isEmpty()) {
if (this.gsis.isEmpty()) {
this.gsis = new LinkedHashMap>();
}
this.gsis.put(keyType, names);
}
}
return this;
}
/**
* Sets the target type.
* @param targetType The target type.
* @return This builder instance for chaining.
*/
public Builder withTargetType(final Class targetType) {
this.targetType = targetType;
return this;
}
/**
* Sets the attribute name.
* @param attributeName The attribute name.
* @return This builder instance for chaining.
*/
public Builder withAttributeName(final String attributeName) {
this.attributeName = attributeName;
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Class targetType() {
return targetType;
}
/**
* {@inheritDoc}
*/
@Override
public String attributeName() {
return attributeName;
}
/**
* {@inheritDoc}
*/
@Override
public KeyType keyType() {
return keyType;
}
/**
* {@inheritDoc}
*/
@Override
public List globalSecondaryIndexNames(final KeyType keyType) {
return gsis.containsKey(keyType) ? gsis.get(keyType) : Collections.emptyList();
}
/**
* {@inheritDoc}
*/
@Override
public List localSecondaryIndexNames() {
return lsis;
}
/**
* {@inheritDoc}
*/
@Override
public DynamoDBAutoGenerator autoGenerator() {
return autoGenerator;
}
}
}
/**
* {@link DynamoDBMapperFieldModel} builder.
*/
static class Builder {
private final Id id;
private final Properties.Builder properties;
private DynamoDBMapperValueConverter converter;
private Reflect reflect;
/**
* Construts a new builder.
* @param type The object type.
* @param name The attribute name.
* @param defaults The default properties.
*/
public Builder(final Id id, final Properties defaults) {
this.properties = new Properties.Builder().with(defaults).withAttributeName(id.name());
this.id = id;
}
/**
* Sets the object's reflection property.
* @param reflect The object's refleciton property.
* @return This builder instance for chaining.
*/
public Builder with(final Reflect reflect) {
this.reflect = reflect;
return this;
}
/**
* Sets the attribute value converter.
* @param converter The attribute value converter.
* @return This builder instance for chaining.
*/
public Builder with(final DynamoDBMapperValueConverter converter) {
this.converter = converter;
return this;
}
/**
* Builds the instance.
* @return The built instance.
*/
public final DynamoDBMapperFieldModel build() {
final DynamoDBMapperFieldModel field = new DynamoDBMapperFieldModel(this);
if (field.keyType() != null && field.getGenerateStrategy() == DynamoDBAutoGenerateStrategy.ALWAYS) {
throw new DynamoDBMappingException(id.format("must not have auto-generated key with ALWAYS strategy"));
}
return field;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy