diff --git a/pom.xml b/pom.xml
index 2917aeb0..5c1acd37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-keyvalue
- 0.1.0.BUILD-SNAPSHOT
+ 0.1.0.DATAKV-101-SNAPSHOT
Spring Data KeyValue
diff --git a/src/main/java/org/springframework/data/keyvalue/core/IterableConverter.java b/src/main/java/org/springframework/data/keyvalue/core/IterableConverter.java
new file mode 100644
index 00000000..8cc093e6
--- /dev/null
+++ b/src/main/java/org/springframework/data/keyvalue/core/IterableConverter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2015 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.springframework.data.keyvalue.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Converter capable of transforming a given {@link Iterable} into a collection type.
+ *
+ * @author Christoph Strobl
+ * @param
+ */
+public final class IterableConverter {
+
+ private IterableConverter() {}
+
+ /**
+ * Converts a given {@link Iterable} into a {@link List}
+ *
+ * @param source
+ * @return {@link Collections#emptyList()} when source is {@literal null}.
+ */
+ public static List toList(Iterable source) {
+
+ if (source == null) {
+ return Collections.emptyList();
+ }
+
+ if (source instanceof List) {
+ return (List) source;
+ }
+
+ if (source instanceof Collection) {
+ return new ArrayList((Collection) source);
+ }
+
+ List result = new ArrayList();
+ for (T value : source) {
+ result.add(value);
+ }
+ return result;
+ }
+}
diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java
index 70ccbaba..14a0477a 100644
--- a/src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java
+++ b/src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java
@@ -71,7 +71,7 @@ public interface KeyValueAdapter extends DisposableBean {
* @param keyspace must not be {@literal null}.
* @return empty {@link Collection} if nothing found.
*/
- Collection> getAllOf(Serializable keyspace);
+ Iterable> getAllOf(Serializable keyspace);
/**
* Returns a {@link KeyValueIterator} that iterates over all entries.
@@ -100,7 +100,14 @@ public interface KeyValueAdapter extends DisposableBean {
* @param keyspace must not be {@literal null}.
* @return empty {@link Collection} if no match found.
*/
- Collection> find(KeyValueQuery> query, Serializable keyspace);
+ Iterable> find(KeyValueQuery> query, Serializable keyspace);
+
+ /**
+ * Count number of objects within {@literal keyspace}.
+ *
+ * @param keyspace must not be {@literal null}.
+ */
+ long count(Serializable keyspace);
/**
* Count all matching objects within {@literal keyspace}.
diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java
index 3851c812..3e17f714 100644
--- a/src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java
+++ b/src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java
@@ -16,7 +16,6 @@
package org.springframework.data.keyvalue.core;
import java.io.Serializable;
-import java.util.List;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.data.domain.Sort;
@@ -52,9 +51,9 @@ public interface KeyValueOperations extends DisposableBean {
* assigned to requested type.
*
* @param type must not be {@literal null}.
- * @return empty collection if no elements found.
+ * @return empty iterable if no elements found.
*/
- List findAll(Class type);
+ Iterable findAll(Class type);
/**
* Get all elements ordered by sort. Respects {@link KeySpace} if present and therefore returns all elements that can
@@ -64,7 +63,7 @@ public interface KeyValueOperations extends DisposableBean {
* @param type must not be {@literal null}.
* @return
*/
- List findAll(Sort sort, Class type);
+ Iterable findAll(Sort sort, Class type);
/**
* Get element of given type with given id. Respects {@link KeySpace} if present and therefore returns all elements
@@ -90,9 +89,9 @@ public interface KeyValueOperations extends DisposableBean {
*
* @param query must not be {@literal null}.
* @param type must not be {@literal null}.
- * @return empty collection if no match found.
+ * @return empty iterable if no match found.
*/
- List find(KeyValueQuery> query, Class type);
+ Iterable find(KeyValueQuery> query, Class type);
/**
* Get all elements in given range. Respects {@link KeySpace} if present and therefore returns all elements that can
@@ -103,7 +102,7 @@ public interface KeyValueOperations extends DisposableBean {
* @param type must not be {@literal null}.
* @return
*/
- List findInRange(int offset, int rows, Class type);
+ Iterable findInRange(int offset, int rows, Class type);
/**
* Get all elements in given range ordered by sort. Respects {@link KeySpace} if present and therefore returns all
@@ -115,7 +114,7 @@ public interface KeyValueOperations extends DisposableBean {
* @param type
* @return
*/
- List findInRange(int offset, int rows, Sort sort, Class type);
+ Iterable findInRange(int offset, int rows, Sort sort, Class type);
/**
* @param objectToUpdate must not be {@literal null}.
diff --git a/src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java b/src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java
index 6d677226..72180539 100644
--- a/src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java
+++ b/src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java
@@ -19,7 +19,6 @@
import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -203,14 +202,14 @@ public List findAll(final Class type) {
@Override
public List doInKeyValue(KeyValueAdapter adapter) {
- Collection> x = adapter.getAllOf(resolveKeySpace(type));
+ Iterable> values = adapter.getAllOf(resolveKeySpace(type));
if (getKeySpace(type) == null) {
- return new ArrayList((Collection) x);
+ return new ArrayList(IterableConverter.toList((Iterable) values));
}
ArrayList filtered = new ArrayList();
- for (Object candidate : x) {
+ for (Object candidate : values) {
if (typeCheck(type, candidate)) {
filtered.add((T) candidate);
}
@@ -332,7 +331,7 @@ public T doInKeyValue(KeyValueAdapter adapter) {
public long count(Class> type) {
Assert.notNull(type, "Type for count must not be null!");
- return findAll(type).size();
+ return adapter.count(resolveKeySpace(type));
}
/*
@@ -364,10 +363,10 @@ public List find(final KeyValueQuery> query, final Class type) {
@Override
public List doInKeyValue(KeyValueAdapter adapter) {
- Collection> result = adapter.find(query, resolveKeySpace(type));
+ Iterable> result = adapter.find(query, resolveKeySpace(type));
if (getKeySpace(type) == null) {
- return new ArrayList((Collection) result);
+ return new ArrayList(IterableConverter.toList((Iterable) result));
}
List filtered = new ArrayList();
@@ -517,7 +516,7 @@ private RuntimeException resolveExceptionIfPossible(RuntimeException e) {
}
private void potentiallyPublishEvent(KeyValueEvent event) {
-
+
if (eventPublisher == null) {
return;
}
diff --git a/src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java b/src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java
index 6b7977a3..e472dc37 100644
--- a/src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java
+++ b/src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java
@@ -65,10 +65,10 @@ public long count(SpelExpression criteria, Serializable keyspace) {
}
@SuppressWarnings({ "unchecked", "rawtypes" })
- private List> sortAndFilterMatchingRange(Collection> source, SpelExpression criteria, Comparator sort,
- int offset, int rows) {
+ private List> sortAndFilterMatchingRange(Iterable> source, SpelExpression criteria, Comparator sort, int offset,
+ int rows) {
- List> tmp = new ArrayList(source);
+ List> tmp = IterableConverter.toList(source);
if (sort != null) {
Collections.sort(tmp, sort);
}
diff --git a/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java b/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java
index 764aceb2..efa7b279 100644
--- a/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java
+++ b/src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java
@@ -16,11 +16,11 @@
package org.springframework.data.keyvalue.repository.query;
import java.lang.reflect.Constructor;
-import java.util.List;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
+import org.springframework.data.keyvalue.core.IterableConverter;
import org.springframework.data.keyvalue.core.KeyValueOperations;
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
import org.springframework.data.repository.query.EvaluationContextProvider;
@@ -33,7 +33,6 @@
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.spel.standard.SpelExpression;
import org.springframework.util.ClassUtils;
-import org.springframework.util.CollectionUtils;
/**
* {@link RepositoryQuery} implementation deriving queries from {@link PartTree} using a predefined
@@ -77,12 +76,12 @@ public Object execute(Object[] parameters) {
query.setOffset(page.getOffset());
query.setRows(page.getPageSize());
- List> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
+ Iterable> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
long count = queryMethod.isSliceQuery() ? 0 : keyValueOperations.count(query, queryMethod.getEntityInformation()
.getJavaType());
- return new PageImpl(result, page, count);
+ return new PageImpl(IterableConverter.toList(result), page, count);
} else if (queryMethod.isCollectionQuery()) {
@@ -90,8 +89,8 @@ public Object execute(Object[] parameters) {
} else if (queryMethod.isQueryForEntity()) {
- List> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
- return CollectionUtils.isEmpty(result) ? null : result.get(0);
+ Iterable> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
+ return result.iterator().hasNext() ? result.iterator().next() : null;
}
diff --git a/src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java b/src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java
index 5ab9d897..91ff53a3 100644
--- a/src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java
+++ b/src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java
@@ -23,6 +23,7 @@
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
+import org.springframework.data.keyvalue.core.IterableConverter;
import org.springframework.data.keyvalue.core.KeyValueOperations;
import org.springframework.data.keyvalue.repository.KeyValueRepository;
import org.springframework.data.repository.core.EntityInformation;
@@ -76,12 +77,11 @@ public Page findAll(Pageable pageable) {
return new PageImpl(result, null, result.size());
}
- List content = null;
-
- content = operations.findInRange(pageable.getOffset(), pageable.getPageSize(), pageable.getSort(),
+ Iterable content = operations.findInRange(pageable.getOffset(), pageable.getPageSize(), pageable.getSort(),
entityInformation.getJavaType());
- return new PageImpl(content, pageable, this.operations.count(entityInformation.getJavaType()));
+ return new PageImpl(IterableConverter.toList(content), pageable, this.operations.count(entityInformation
+ .getJavaType()));
}
/*
@@ -139,7 +139,7 @@ public boolean exists(ID id) {
*/
@Override
public List findAll() {
- return operations.findAll(entityInformation.getJavaType());
+ return IterableConverter.toList(operations.findAll(entityInformation.getJavaType()));
}
/*
diff --git a/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java b/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java
index 3e9695c5..4c0acc85 100644
--- a/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java
+++ b/src/main/java/org/springframework/data/map/MapKeyValueAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 the original author or authors.
+ * Copyright 2014-2015 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.
@@ -104,6 +104,15 @@ public boolean contains(Serializable id, Serializable keyspace) {
return get(id, keyspace) != null;
}
+
+ /* (non-Javadoc)
+ * @see org.springframework.data.keyvalue.core.KeyValueAdapter#count(java.io.Serializable)
+ */
+ @Override
+ public long count(Serializable keyspace) {
+ return getKeySpaceMap(keyspace).size();
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.keyvalue.core.KeyValueAdapter#get(java.io.Serializable, java.io.Serializable)
diff --git a/src/test/java/org/springframework/data/keyvalue/core/IterableConverterUnitTests.java b/src/test/java/org/springframework/data/keyvalue/core/IterableConverterUnitTests.java
new file mode 100644
index 00000000..382f98ba
--- /dev/null
+++ b/src/test/java/org/springframework/data/keyvalue/core/IterableConverterUnitTests.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 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.springframework.data.keyvalue.core;
+
+import static org.hamcrest.collection.IsEmptyCollection.*;
+import static org.hamcrest.collection.IsIterableContainingInOrder.*;
+import static org.hamcrest.core.IsInstanceOf.*;
+import static org.hamcrest.core.IsNull.*;
+import static org.hamcrest.core.IsSame.*;
+import static org.junit.Assert.*;
+import static org.springframework.data.keyvalue.core.IterableConverter.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.Test;
+
+/**
+ * @author Christoph Strobl
+ */
+public class IterableConverterUnitTests {
+
+ /**
+ * @see DATAKV-101
+ */
+ @Test
+ public void toListShouldReturnEmptyListWhenSourceIsNull() {
+ assertThat(toList(null), notNullValue());
+ }
+
+ /**
+ * @see DATAKV-101
+ */
+ @Test
+ public void toListShouldReturnEmptyListWhenSourceEmpty() {
+ assertThat(toList(Collections.emptySet()), empty());
+ }
+
+ /**
+ * @see DATAKV-101
+ */
+ @Test
+ public void toListShouldReturnSameObjectWhenSourceIsAlreadyListType() {
+
+ List source = new ArrayList();
+
+ assertThat(toList(source), sameInstance(source));
+ }
+
+ /**
+ * @see DATAKV-101
+ */
+ @Test
+ public void toListShouldReturnListWhenSourceIsNonListType() {
+
+ Set source = new HashSet();
+ source.add("tyrion");
+
+ assertThat(toList(source), instanceOf(List.class));
+ }
+
+ /**
+ * @see DATAKV-101
+ */
+ @Test
+ public void toListShouldHoldValuesInOrderOfSource() {
+
+ Set source = new LinkedHashSet();
+ source.add("tyrion");
+ source.add("jaime");
+
+ assertThat(toList(source), contains(source.toArray(new String[2])));
+ }
+
+}
diff --git a/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java b/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java
index 5402f860..80e183c6 100644
--- a/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java
+++ b/src/test/java/org/springframework/data/keyvalue/core/KeyValueTemplateUnitTests.java
@@ -362,11 +362,9 @@ public void countShouldReturnZeroWhenNoElementsPresent() {
* @see DATACMNS-525
*/
@Test
- @SuppressWarnings({ "rawtypes", "unchecked" })
public void countShouldReturnCollectionSize() {
- Collection foo = Arrays.asList(FOO_ONE, FOO_ONE);
- when(adapterMock.getAllOf(Foo.class.getName())).thenReturn(foo);
+ when(adapterMock.count(Foo.class.getName())).thenReturn(2L);
assertThat(template.count(Foo.class), is(2L));
}