package com.amazonaws.mobileconnectors.dynamodbv2.document;
import com.amazonaws.mobileconnectors.dynamodbv2.document.datatype.Document;
import com.amazonaws.mobileconnectors.dynamodbv2.document.datatype.DynamoDBEntry;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.DeleteItemRequest;
import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
import com.amazonaws.services.dynamodbv2.model.QueryRequest;
import com.amazonaws.services.dynamodbv2.model.ScanRequest;
import com.amazonaws.services.dynamodbv2.model.UpdateItemRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
/**
*
* Expressions are used for conditional deletes and filtering for query and scan
* operations.
*
*/
public class Expression {
protected boolean isSet() {
return this.expressionStatement != null;
}
/**
*
* Gets and sets the property ExpressionStatement. "Price > :price" is an
* example expression statement. :price is a variable which gets its value
* from the ExpressionAttributeValues collection. If this is used for
* deletes then it prevents the delete from happening if the Price attribute
* on the item is less then the passed in price. For query and scan it will
* only return back items where the Price attribute is greater then passed
* in price.
*
*/
private String expressionStatement;
/**
*
* This collection contains attribute names from the item that should be
* substituted in the expression when it is evaluated. For example the
* expression "#C < #U" will expect the attribute names to be added to
* this collection.
* expression.ExpressionAttributeNames["#C"] = "CriticRating"
* expression.ExpressionAttributeNames["#U"] = "UserRating"
*
*
*/
private final Map expressionAttributeNames = new HashMap();
/**
* Adds expression attributes.
*
* @param key the attribute name.
* @param value the atttribute value.
*/
public void addExpressionAttributeNames(String key, String value) {
this.expressionAttributeNames.put(key, value);
}
/**
* Adds expression attributes.
*
* @param key the attribute name.
* @param value the atttribute value.
* @return {@link Expression}.
*/
public Expression withExpressionAttibuteNames(String key, String value) {
addExpressionAttributeNames(key, value);
return this;
}
/**
*
* Gets and sets the property ExpressionAttributeValues. This collection
* contains the values to be substituted in the expression. For example the
* expression "Price > :price" will contain one entry in this collection a
* key of ":price".
*
* DynamoDBEntry contains many common implicit cast operations so assignment
* can be done with the basic .NET types. In the price example shown above
* the value to be used for the expression can be provided using the
* following code snippet:
* expression.ExpressionAttributeNames[":price"] = 3.99;
*
*
*
*/
private final Map expressionAttributeValues = new HashMap();
/**
* Adds expression attribute values.
*
* @param key the expression attribute name.
* @param value the expression attribute value.
*/
public void addExpressionAttributeValues(String key, DynamoDBEntry value) {
this.expressionAttributeValues.put(key, value);
}
/**
* Adds expression attribute values.
*
* @param key the expression attribute name.
* @param value the expression attribute value.
* @return {@link Expression}.
*/
public Expression withExpressionAttibuteValues(String key, DynamoDBEntry value) {
addExpressionAttributeValues(key, value);
return this;
}
protected void applyExpression(ScanRequest request, Table table) {
request.setFilterExpression(this.expressionStatement);
if (this.expressionAttributeNames != null && !this.expressionAttributeNames.isEmpty()) {
request.setExpressionAttributeNames(new HashMap(
this.expressionAttributeNames));
}
request.setExpressionAttributeValues(convertToAttributeValues(
this.expressionAttributeValues, table));
}
protected void applyExpression(DeleteItemRequest request, Table table) {
request.setConditionExpression(this.expressionStatement);
if (this.expressionAttributeNames != null && !this.expressionAttributeNames.isEmpty()) {
request.setExpressionAttributeNames(
new HashMap(this.expressionAttributeNames));
}
request.setExpressionAttributeValues(
convertToAttributeValues(this.expressionAttributeValues, table));
}
protected void applyExpression(PutItemRequest request, Table table) {
request.setConditionExpression(this.expressionStatement);
if (this.expressionAttributeNames != null && !this.expressionAttributeNames.isEmpty()) {
request.setExpressionAttributeNames(
new HashMap(this.expressionAttributeNames));
}
request.setExpressionAttributeValues(
convertToAttributeValues(this.expressionAttributeValues, table));
}
protected void applyExpression(UpdateItemRequest request, Table table) {
request.setConditionExpression(this.expressionStatement);
if (this.expressionAttributeNames != null && !this.expressionAttributeNames.isEmpty()) {
request.setExpressionAttributeNames(
new HashMap(this.expressionAttributeNames));
}
request.setExpressionAttributeValues(
convertToAttributeValues(this.expressionAttributeValues, table));
}
protected static void applyExpression(QueryRequest request, Table table,
Expression keyExpression, Expression filterExpression) {
if (keyExpression == null) {
keyExpression = new Expression();
}
if (filterExpression == null) {
filterExpression = new Expression();
}
if (!keyExpression.isSet() && !filterExpression.isSet()) {
return;
}
if (keyExpression.isSet()) {
request.setKeyConditionExpression(keyExpression.expressionStatement);
}
if (filterExpression.isSet()) {
request.setFilterExpression(filterExpression.expressionStatement);
}
final Map keyExpressionAtrtibuteNames = keyExpression.expressionAttributeNames;
final Map filterExpressionAttributeNames = filterExpression.expressionAttributeNames;
final Map combinedExpressionAttributeNames = new HashMap();
combinedExpressionAttributeNames.putAll(keyExpressionAtrtibuteNames);
combinedExpressionAttributeNames.putAll(filterExpressionAttributeNames);
if (!combinedExpressionAttributeNames.isEmpty()) {
request.setExpressionAttributeNames(combinedExpressionAttributeNames);
}
final Map keyExpressionAttributeValues = new Document(
keyExpression.expressionAttributeValues);
final Map filterExpressionAttributeValues = new Document(
filterExpression.expressionAttributeValues);
final Map combinedKeyExpressionAttributeValues = new Document(
keyExpressionAttributeValues);
combinedKeyExpressionAttributeValues.putAll(filterExpressionAttributeValues);
request.setExpressionAttributeValues(
convertToAttributeValues(combinedKeyExpressionAttributeValues, table));
}
protected static Map convertToAttributeValues(
Map valueMap, Table table) {
final Map convertedValues = new HashMap();
if (valueMap != null) {
for (final Entry kvp : valueMap.entrySet()) {
final String attributeName = kvp.getKey();
final DynamoDBEntry entry = kvp.getValue();
if (entry == null) {
convertedValues.put(attributeName, new AttributeValue().withNULL(true));
} else {
convertedValues.put(attributeName, entry.convertToAttributeValue());
}
}
}
return convertedValues;
}
public String getExpressionStatement() {
return expressionStatement;
}
public void setExpressionStatement(String expressionStatement) {
this.expressionStatement = expressionStatement;
}
}