package org.springframework.data.simpledb.query.executions; import org.springframework.data.simpledb.core.SimpleDbOperations; import org.springframework.data.simpledb.query.QueryUtils; import org.springframework.data.simpledb.query.SimpleDbQueryMethod; import org.springframework.data.simpledb.query.SimpleDbQueryRunner; import org.springframework.data.simpledb.query.SimpleDbResultConverter; import org.springframework.data.simpledb.reflection.ReflectionUtils; import java.util.List; import java.util.Set; /** * Factory class for creating the appropriate type of execution. */ public class MultipleResultExecution extends AbstractSimpleDbQueryExecution { public MultipleResultExecution(SimpleDbOperations simpledbOperations) { super(simpledbOperations); } /** * The following multiple result types can be requested: <br/> * <ul> * <li>COLLECTION_OF_DOMAIN_ENTITIES - {@code List<Entity>} <br/> * as returned type for query <code> select * from entity</code></li> * <li>LIST_OF_LIST_OF_OBJECT - {@code List<List<Object>>} <br/> * as returned type for query <code> select aField, bField from entity</code></li> * <li>FIELD_OF_TYPE_COLLECTION - {@code Collection<?>} <br/> * as returned type for query <code> select collectionField from entity where itemName()="1"</code></li> * <li>LIST_OF_FIELDS - {@code List<?>} <br/> * as returned type for query <code> select aField from entity</code></li> * <li>SET_OF_FIELDS - {@code Set<?>} <br/> * as returned type for query <code> select aField from entity</code></li> * </ul> */ public enum MultipleResultType { COLLECTION_OF_DOMAIN_ENTITIES, LIST_OF_LIST_OF_OBJECT, FIELD_OF_TYPE_COLLECTION, LIST_OF_FIELDS, SET_OF_FIELDS; } @Override protected Object doExecute(SimpleDbQueryMethod method, SimpleDbQueryRunner queryRunner) { MultipleResultType resultType = detectResultType(method); switch(resultType) { case COLLECTION_OF_DOMAIN_ENTITIES: return queryRunner.executeQuery(); case LIST_OF_LIST_OF_OBJECT: List<?> returnList = queryRunner.executeQuery(); List<String> requestedQueryFieldNames = queryRunner.getRequestedQueryFieldNames(); return SimpleDbResultConverter.toListOfListOfObject(returnList, requestedQueryFieldNames); case FIELD_OF_TYPE_COLLECTION: String attributeName = queryRunner.getSingleQueryFieldName(); Object returnedEntity = queryRunner.executeSingleResultQuery(); return ReflectionUtils.callGetter(returnedEntity, attributeName); case LIST_OF_FIELDS: String attributeName1 = queryRunner.getSingleQueryFieldName(); List<?> returnListFromDb = queryRunner.executeQuery(); return SimpleDbResultConverter.filterNamedAttributesAsList(returnListFromDb, attributeName1); case SET_OF_FIELDS: String attributeName3 = queryRunner.getSingleQueryFieldName(); List<?> returnListFromDb1 = queryRunner.executeQuery(); return SimpleDbResultConverter.filterNamedAttributesAsSet(returnListFromDb1, attributeName3); } throw new IllegalArgumentException("Unrecognized multiple result type"); } MultipleResultType detectResultType(SimpleDbQueryMethod method) { String query = method.getAnnotatedQuery(); if(method.returnsCollectionOfDomainClass()) { return MultipleResultType.COLLECTION_OF_DOMAIN_ENTITIES; } else if(QueryUtils.getQueryPartialFieldNames(query).size() > 1) { return MultipleResultType.LIST_OF_LIST_OF_OBJECT; } else { if(method.returnsListOfListOfObject()) { return MultipleResultType.LIST_OF_LIST_OF_OBJECT; } else if(method.returnsFieldOfTypeCollection()) { return MultipleResultType.FIELD_OF_TYPE_COLLECTION; } else if(List.class.isAssignableFrom(method.getReturnType())) { return MultipleResultType.LIST_OF_FIELDS; } else if(Set.class.isAssignableFrom(method.getReturnType())) { return MultipleResultType.SET_OF_FIELDS; } else { throw new IllegalArgumentException("Wrong return type for query: " + query); } } } }