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; } }