Skip to content

Commit 952a901

Browse files
christophstroblThomas Darimont
authored and
Thomas Darimont
committed
DATAKV-101 - Favor Iterable over Collection types for KeyValueOperations.
Change return types for Adapter and Operations from Collection types to Iterable. Added count(keyspace) to KeyValueAdapter. Original pull request: #8.
1 parent 16dc4b5 commit 952a901

File tree

10 files changed

+198
-36
lines changed

10 files changed

+198
-36
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright 2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.keyvalue.core;
17+
18+
import java.util.ArrayList;
19+
import java.util.Collection;
20+
import java.util.Collections;
21+
import java.util.List;
22+
23+
/**
24+
* Converter capable of transforming a given {@link Iterable} into a collection type.
25+
*
26+
* @author Christoph Strobl
27+
* @param <T>
28+
*/
29+
public final class IterableConverter {
30+
31+
private IterableConverter() {}
32+
33+
/**
34+
* Converts a given {@link Iterable} into a {@link List}
35+
*
36+
* @param source
37+
* @return {@link Collections#emptyList()} when source is {@literal null}.
38+
*/
39+
public static <T> List<T> toList(Iterable<T> source) {
40+
41+
if (source == null) {
42+
return Collections.emptyList();
43+
}
44+
45+
if (source instanceof List) {
46+
return (List<T>) source;
47+
}
48+
49+
if (source instanceof Collection) {
50+
return new ArrayList<T>((Collection<T>) source);
51+
}
52+
53+
List<T> result = new ArrayList<T>();
54+
for (T value : source) {
55+
result.add(value);
56+
}
57+
return result;
58+
}
59+
}

src/main/java/org/springframework/data/keyvalue/core/KeyValueAdapter.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public interface KeyValueAdapter extends DisposableBean {
7171
* @param keyspace must not be {@literal null}.
7272
* @return empty {@link Collection} if nothing found.
7373
*/
74-
Collection<?> getAllOf(Serializable keyspace);
74+
Iterable<?> getAllOf(Serializable keyspace);
7575

7676
/**
7777
* Returns a {@link KeyValueIterator} that iterates over all entries.
@@ -100,7 +100,14 @@ public interface KeyValueAdapter extends DisposableBean {
100100
* @param keyspace must not be {@literal null}.
101101
* @return empty {@link Collection} if no match found.
102102
*/
103-
Collection<?> find(KeyValueQuery<?> query, Serializable keyspace);
103+
Iterable<?> find(KeyValueQuery<?> query, Serializable keyspace);
104+
105+
/**
106+
* Count number of objects within {@literal keyspace}.
107+
*
108+
* @param keyspace must not be {@literal null}.
109+
*/
110+
long count(Serializable keyspace);
104111

105112
/**
106113
* Count all matching objects within {@literal keyspace}.

src/main/java/org/springframework/data/keyvalue/core/KeyValueOperations.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.springframework.data.keyvalue.core;
1717

1818
import java.io.Serializable;
19-
import java.util.List;
2019

2120
import org.springframework.beans.factory.DisposableBean;
2221
import org.springframework.data.domain.Sort;
@@ -52,9 +51,9 @@ public interface KeyValueOperations extends DisposableBean {
5251
* assigned to requested type.
5352
*
5453
* @param type must not be {@literal null}.
55-
* @return empty collection if no elements found.
54+
* @return empty iterable if no elements found.
5655
*/
57-
<T> List<T> findAll(Class<T> type);
56+
<T> Iterable<T> findAll(Class<T> type);
5857

5958
/**
6059
* 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 {
6463
* @param type must not be {@literal null}.
6564
* @return
6665
*/
67-
<T> List<T> findAll(Sort sort, Class<T> type);
66+
<T> Iterable<T> findAll(Sort sort, Class<T> type);
6867

6968
/**
7069
* 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 {
9089
*
9190
* @param query must not be {@literal null}.
9291
* @param type must not be {@literal null}.
93-
* @return empty collection if no match found.
92+
* @return empty iterable if no match found.
9493
*/
95-
<T> List<T> find(KeyValueQuery<?> query, Class<T> type);
94+
<T> Iterable<T> find(KeyValueQuery<?> query, Class<T> type);
9695

9796
/**
9897
* 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 {
103102
* @param type must not be {@literal null}.
104103
* @return
105104
*/
106-
<T> List<T> findInRange(int offset, int rows, Class<T> type);
105+
<T> Iterable<T> findInRange(int offset, int rows, Class<T> type);
107106

108107
/**
109108
* 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 {
115114
* @param type
116115
* @return
117116
*/
118-
<T> List<T> findInRange(int offset, int rows, Sort sort, Class<T> type);
117+
<T> Iterable<T> findInRange(int offset, int rows, Sort sort, Class<T> type);
119118

120119
/**
121120
* @param objectToUpdate must not be {@literal null}.

src/main/java/org/springframework/data/keyvalue/core/KeyValueTemplate.java

+7-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import java.io.Serializable;
2121
import java.util.ArrayList;
22-
import java.util.Collection;
2322
import java.util.Collections;
2423
import java.util.HashSet;
2524
import java.util.List;
@@ -203,14 +202,14 @@ public <T> List<T> findAll(final Class<T> type) {
203202
@Override
204203
public List<T> doInKeyValue(KeyValueAdapter adapter) {
205204

206-
Collection<?> x = adapter.getAllOf(resolveKeySpace(type));
205+
Iterable<?> values = adapter.getAllOf(resolveKeySpace(type));
207206

208207
if (getKeySpace(type) == null) {
209-
return new ArrayList<T>((Collection<T>) x);
208+
return new ArrayList<T>(IterableConverter.toList((Iterable<T>) values));
210209
}
211210

212211
ArrayList<T> filtered = new ArrayList<T>();
213-
for (Object candidate : x) {
212+
for (Object candidate : values) {
214213
if (typeCheck(type, candidate)) {
215214
filtered.add((T) candidate);
216215
}
@@ -332,7 +331,7 @@ public T doInKeyValue(KeyValueAdapter adapter) {
332331
public long count(Class<?> type) {
333332

334333
Assert.notNull(type, "Type for count must not be null!");
335-
return findAll(type).size();
334+
return adapter.count(resolveKeySpace(type));
336335
}
337336

338337
/*
@@ -364,10 +363,10 @@ public <T> List<T> find(final KeyValueQuery<?> query, final Class<T> type) {
364363
@Override
365364
public List<T> doInKeyValue(KeyValueAdapter adapter) {
366365

367-
Collection<?> result = adapter.find(query, resolveKeySpace(type));
366+
Iterable<?> result = adapter.find(query, resolveKeySpace(type));
368367

369368
if (getKeySpace(type) == null) {
370-
return new ArrayList<T>((Collection<T>) result);
369+
return new ArrayList<T>(IterableConverter.toList((Iterable<T>) result));
371370
}
372371

373372
List<T> filtered = new ArrayList<T>();
@@ -517,7 +516,7 @@ private RuntimeException resolveExceptionIfPossible(RuntimeException e) {
517516
}
518517

519518
private void potentiallyPublishEvent(KeyValueEvent event) {
520-
519+
521520
if (eventPublisher == null) {
522521
return;
523522
}

src/main/java/org/springframework/data/keyvalue/core/SpelQueryEngine.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ public long count(SpelExpression criteria, Serializable keyspace) {
6565
}
6666

6767
@SuppressWarnings({ "unchecked", "rawtypes" })
68-
private List<?> sortAndFilterMatchingRange(Collection<?> source, SpelExpression criteria, Comparator sort,
69-
int offset, int rows) {
68+
private List<?> sortAndFilterMatchingRange(Iterable<?> source, SpelExpression criteria, Comparator sort, int offset,
69+
int rows) {
7070

71-
List<?> tmp = new ArrayList(source);
71+
List<?> tmp = IterableConverter.toList(source);
7272
if (sort != null) {
7373
Collections.sort(tmp, sort);
7474
}

src/main/java/org/springframework/data/keyvalue/repository/query/KeyValuePartTreeQuery.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
package org.springframework.data.keyvalue.repository.query;
1717

1818
import java.lang.reflect.Constructor;
19-
import java.util.List;
2019

2120
import org.springframework.beans.BeanUtils;
2221
import org.springframework.data.domain.PageImpl;
2322
import org.springframework.data.domain.Pageable;
23+
import org.springframework.data.keyvalue.core.IterableConverter;
2424
import org.springframework.data.keyvalue.core.KeyValueOperations;
2525
import org.springframework.data.keyvalue.core.query.KeyValueQuery;
2626
import org.springframework.data.repository.query.EvaluationContextProvider;
@@ -33,7 +33,6 @@
3333
import org.springframework.expression.EvaluationContext;
3434
import org.springframework.expression.spel.standard.SpelExpression;
3535
import org.springframework.util.ClassUtils;
36-
import org.springframework.util.CollectionUtils;
3736

3837
/**
3938
* {@link RepositoryQuery} implementation deriving queries from {@link PartTree} using a predefined
@@ -77,21 +76,21 @@ public Object execute(Object[] parameters) {
7776
query.setOffset(page.getOffset());
7877
query.setRows(page.getPageSize());
7978

80-
List<?> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
79+
Iterable<?> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
8180

8281
long count = queryMethod.isSliceQuery() ? 0 : keyValueOperations.count(query, queryMethod.getEntityInformation()
8382
.getJavaType());
8483

85-
return new PageImpl(result, page, count);
84+
return new PageImpl(IterableConverter.toList(result), page, count);
8685

8786
} else if (queryMethod.isCollectionQuery()) {
8887

8988
return this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
9089

9190
} else if (queryMethod.isQueryForEntity()) {
9291

93-
List<?> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
94-
return CollectionUtils.isEmpty(result) ? null : result.get(0);
92+
Iterable<?> result = this.keyValueOperations.find(query, queryMethod.getEntityInformation().getJavaType());
93+
return result.iterator().hasNext() ? result.iterator().next() : null;
9594

9695
}
9796

src/main/java/org/springframework/data/keyvalue/repository/support/SimpleKeyValueRepository.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.data.domain.PageImpl;
2424
import org.springframework.data.domain.Pageable;
2525
import org.springframework.data.domain.Sort;
26+
import org.springframework.data.keyvalue.core.IterableConverter;
2627
import org.springframework.data.keyvalue.core.KeyValueOperations;
2728
import org.springframework.data.keyvalue.repository.KeyValueRepository;
2829
import org.springframework.data.repository.core.EntityInformation;
@@ -76,12 +77,11 @@ public Page<T> findAll(Pageable pageable) {
7677
return new PageImpl<T>(result, null, result.size());
7778
}
7879

79-
List<T> content = null;
80-
81-
content = operations.findInRange(pageable.getOffset(), pageable.getPageSize(), pageable.getSort(),
80+
Iterable<T> content = operations.findInRange(pageable.getOffset(), pageable.getPageSize(), pageable.getSort(),
8281
entityInformation.getJavaType());
8382

84-
return new PageImpl<T>(content, pageable, this.operations.count(entityInformation.getJavaType()));
83+
return new PageImpl<T>(IterableConverter.toList(content), pageable, this.operations.count(entityInformation
84+
.getJavaType()));
8585
}
8686

8787
/*
@@ -139,7 +139,7 @@ public boolean exists(ID id) {
139139
*/
140140
@Override
141141
public List<T> findAll() {
142-
return operations.findAll(entityInformation.getJavaType());
142+
return IterableConverter.toList(operations.findAll(entityInformation.getJavaType()));
143143
}
144144

145145
/*

src/main/java/org/springframework/data/map/MapKeyValueAdapter.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014 the original author or authors.
2+
* Copyright 2014-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -104,6 +104,15 @@ public boolean contains(Serializable id, Serializable keyspace) {
104104
return get(id, keyspace) != null;
105105
}
106106

107+
108+
/* (non-Javadoc)
109+
* @see org.springframework.data.keyvalue.core.KeyValueAdapter#count(java.io.Serializable)
110+
*/
111+
@Override
112+
public long count(Serializable keyspace) {
113+
return getKeySpaceMap(keyspace).size();
114+
}
115+
107116
/*
108117
* (non-Javadoc)
109118
* @see org.springframework.data.keyvalue.core.KeyValueAdapter#get(java.io.Serializable, java.io.Serializable)

0 commit comments

Comments
 (0)