/* * Copyright 2013 the original author or authors. * * 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://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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 org.socialsignin.spring.data.dynamodb.repository.support; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.socialsignin.spring.data.dynamodb.core.DynamoDBOperations; import org.socialsignin.spring.data.dynamodb.repository.DynamoDBCrudRepository; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.util.Assert; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression; import com.amazonaws.services.dynamodbv2.datamodeling.KeyPair; /** * Default implementation of the * {@link org.springframework.data.repository.CrudRepository} interface. * * @author Michael Lavelle * * @param <T> * the type of the entity to handle * @param <ID> * the type of the entity's identifier */ public class SimpleDynamoDBCrudRepository<T, ID extends Serializable> implements DynamoDBCrudRepository<T, ID> { protected DynamoDBEntityInformation<T, ID> entityInformation; protected Class<T> domainType; protected EnableScanPermissions enableScanPermissions; protected DynamoDBOperations dynamoDBOperations; public SimpleDynamoDBCrudRepository( DynamoDBEntityInformation<T, ID> entityInformation, DynamoDBOperations dynamoDBOperations, EnableScanPermissions enableScanPermissions) { Assert.notNull(entityInformation); Assert.notNull(dynamoDBOperations); this.entityInformation = entityInformation; this.dynamoDBOperations = dynamoDBOperations; this.domainType = entityInformation.getJavaType(); this.enableScanPermissions = enableScanPermissions; } @Override public T findOne(ID id) { if (entityInformation.isRangeKeyAware()) { return dynamoDBOperations.load(domainType, entityInformation.getHashKey(id), entityInformation.getRangeKey(id)); } else { return dynamoDBOperations.load(domainType, entityInformation.getHashKey(id)); } } @SuppressWarnings("unchecked") public List<T> findAll(Iterable<ID> ids) { Map<Class<?>, List<KeyPair>> keyPairsMap = new HashMap<Class<?>, List<KeyPair>>(); List<KeyPair> keyPairs = new ArrayList<KeyPair>(); for (ID id : ids) { if (entityInformation.isRangeKeyAware()) { keyPairs.add(new KeyPair().withHashKey( entityInformation.getHashKey(id)).withRangeKey( entityInformation.getRangeKey(id))); } else { keyPairs.add(new KeyPair().withHashKey(id)); } } keyPairsMap.put(domainType, keyPairs); return (List<T>) dynamoDBOperations.batchLoad(keyPairsMap).get(dynamoDBOperations.getOverriddenTableName(entityInformation.getDynamoDBTableName())); } protected T load(ID id) { if (entityInformation.isRangeKeyAware()) { return dynamoDBOperations.load(domainType, entityInformation.getHashKey(id), entityInformation.getRangeKey(id)); } else { return dynamoDBOperations.load(domainType, entityInformation.getHashKey(id)); } } @SuppressWarnings("unchecked") protected List<T> loadBatch(Iterable<ID> ids) { Map<Class<?>, List<KeyPair>> keyPairsMap = new HashMap<Class<?>, List<KeyPair>>(); List<KeyPair> keyPairs = new ArrayList<KeyPair>(); for (ID id : ids) { if (entityInformation.isRangeKeyAware()) { keyPairs.add(new KeyPair().withHashKey( entityInformation.getHashKey(id)).withRangeKey( entityInformation.getRangeKey(id))); } else { keyPairs.add(new KeyPair().withHashKey(id)); } } keyPairsMap.put(domainType, keyPairs); return (List<T>) dynamoDBOperations.batchLoad(keyPairsMap).get(domainType); } @Override public <S extends T> S save(S entity) { dynamoDBOperations.save(entity); return entity; } @Override public <S extends T> List<S> save(Iterable<S> entities) { final List<S> entityList = new ArrayList<S>(); for (S entity : entities) { entityList.add(entity); } dynamoDBOperations.batchSave(entityList); return entityList; } @Override public boolean exists(ID id) { Assert.notNull(id, "The given id must not be null!"); return findOne(id) != null; } public void assertScanEnabled(boolean scanEnabled, String methodName) { Assert.isTrue( scanEnabled, "Scanning for unpaginated " + methodName + "() queries is not enabled. " + "To enable, re-implement the " + methodName + "() method in your repository interface and annotate with @EnableScan, or " + "enable scanning for all repository methods by annotating your repository interface with @EnableScan"); } @Override public List<T> findAll() { assertScanEnabled( enableScanPermissions.isFindAllUnpaginatedScanEnabled(), "findAll"); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression(); return dynamoDBOperations.scan(domainType, scanExpression); } @Override public long count() { assertScanEnabled( enableScanPermissions.isCountUnpaginatedScanEnabled(), "count"); final DynamoDBScanExpression scanExpression = new DynamoDBScanExpression(); return dynamoDBOperations.count(domainType, scanExpression); } @Override public void delete(ID id) { Assert.notNull(id, "The given id must not be null!"); T entity = findOne(id); if (entity == null) { throw new EmptyResultDataAccessException(String.format( "No %s entity with id %s exists!", domainType, id), 1); } dynamoDBOperations.delete(entity); } @Override public void delete(T entity) { Assert.notNull(entity, "The entity must not be null!"); dynamoDBOperations.delete(entity); } @Override public void delete(Iterable<? extends T> entities) { Assert.notNull(entities, "The given Iterable of entities not be null!"); List<T> entityList = new ArrayList<T>(); for (T entity : entities) { entityList.add(entity); } dynamoDBOperations.batchDelete(entityList); } @Override public void deleteAll() { assertScanEnabled( enableScanPermissions.isDeleteAllUnpaginatedScanEnabled(), "deleteAll"); dynamoDBOperations.batchDelete(findAll()); } }