Browse Source

DATACMNS-635 - Slice and Page can now be mapped using a Converter.

Introduced a map(Converter converter) method on Slice and Page to be able to easily transform the elements and create a new Slice or Page of the transformation result.

On Java 8 this allows code like this:

Page<String> strings = …;
Page<Integer> ints = strings.map(String::length);
pull/112/head
Oliver Gierke 11 years ago
parent
commit
5cc4811c52
  1. 22
      src/main/java/org/springframework/data/domain/Chunk.java
  2. 13
      src/main/java/org/springframework/data/domain/Page.java
  3. 12
      src/main/java/org/springframework/data/domain/PageImpl.java
  4. 13
      src/main/java/org/springframework/data/domain/Slice.java
  5. 13
      src/main/java/org/springframework/data/domain/SliceImpl.java
  6. 23
      src/test/java/org/springframework/data/domain/PageImplUnitTests.java

22
src/main/java/org/springframework/data/domain/Chunk.java

@ -1,5 +1,5 @@ @@ -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.
@ -21,6 +21,7 @@ import java.util.Collections; @@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
/**
@ -151,6 +152,25 @@ abstract class Chunk<T> implements Slice<T>, Serializable { @@ -151,6 +152,25 @@ abstract class Chunk<T> implements Slice<T>, Serializable {
return content.iterator();
}
/**
* Applies the given {@link Converter} to the content of the {@link Chunk}.
*
* @param converter must not be {@literal null}.
* @return
*/
protected <S> List<S> getConvertedContent(Converter<? super T, ? extends S> converter) {
Assert.notNull(converter, "Converter must not be null!");
List<S> result = new ArrayList<S>(content.size());
for (T element : this) {
result.add(converter.convert(element));
}
return result;
}
/*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)

13
src/main/java/org/springframework/data/domain/Page.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2008-2014 the original author or authors.
* Copyright 2008-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.
@ -15,6 +15,8 @@ @@ -15,6 +15,8 @@
*/
package org.springframework.data.domain;
import org.springframework.core.convert.converter.Converter;
/**
* A page is a sublist of a list of objects. It allows gain information about the position of it in the containing
* entire list.
@ -37,4 +39,13 @@ public interface Page<T> extends Slice<T> { @@ -37,4 +39,13 @@ public interface Page<T> extends Slice<T> {
* @return the total amount of elements
*/
long getTotalElements();
/**
* Returns a new {@link Page} with the content of the current one mapped by the given {@link Converter}.
*
* @param converter must not be {@literal null}.
* @return a new {@link Page} with the content of the current one mapped by the given {@link Converter}.
* @since 1.10
*/
<S> Page<S> map(Converter<? super T, ? extends S> converter);
}

12
src/main/java/org/springframework/data/domain/PageImpl.java

@ -17,6 +17,7 @@ package org.springframework.data.domain; @@ -17,6 +17,7 @@ package org.springframework.data.domain;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
/**
@ -30,6 +31,7 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> { @@ -30,6 +31,7 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
private static final long serialVersionUID = 867755909294344406L;
private final long total;
private final Pageable pageable;
/**
* Constructor of {@code PageImpl}.
@ -45,6 +47,7 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> { @@ -45,6 +47,7 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
Assert.isTrue(total >= content.size(), "Total must not be less than the number of elements given!");
this.total = total;
this.pageable = pageable;
}
/**
@ -93,6 +96,15 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> { @@ -93,6 +96,15 @@ public class PageImpl<T> extends Chunk<T> implements Page<T> {
return !hasNext();
}
/*
* (non-Javadoc)
* @see org.springframework.data.domain.Slice#transform(org.springframework.core.convert.converter.Converter)
*/
@Override
public <S> Page<S> map(Converter<? super T, ? extends S> converter) {
return new PageImpl<S>(getConvertedContent(converter), pageable, total);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()

13
src/main/java/org/springframework/data/domain/Slice.java

@ -1,5 +1,5 @@ @@ -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.
@ -17,6 +17,8 @@ package org.springframework.data.domain; @@ -17,6 +17,8 @@ package org.springframework.data.domain;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
/**
* A slice of data that indicates whether there's a next or previous slice available. Allows to obtain a
* {@link Pageable} to request a previous or next {@link Slice}.
@ -113,4 +115,13 @@ public interface Slice<T> extends Iterable<T> { @@ -113,4 +115,13 @@ public interface Slice<T> extends Iterable<T> {
* @return
*/
Pageable previousPageable();
/**
* Returns a new {@link Slice} with the content of the current one mapped by the given {@link Converter}.
*
* @param converter must not be {@literal null}.
* @return a new {@link Slice} with the content of the current one mapped by the given {@link Converter}.
* @since 1.10
*/
<S> Slice<S> map(Converter<? super T, ? extends S> converter);
}

13
src/main/java/org/springframework/data/domain/SliceImpl.java

@ -17,6 +17,8 @@ package org.springframework.data.domain; @@ -17,6 +17,8 @@ package org.springframework.data.domain;
import java.util.List;
import org.springframework.core.convert.converter.Converter;
/**
* Default implementation of {@link Slice}.
*
@ -28,6 +30,7 @@ public class SliceImpl<T> extends Chunk<T> { @@ -28,6 +30,7 @@ public class SliceImpl<T> extends Chunk<T> {
private static final long serialVersionUID = 867755909294344406L;
private final boolean hasNext;
private final Pageable pageable;
/**
* Creates a new {@link Slice} with the given content and {@link Pageable}.
@ -40,6 +43,7 @@ public class SliceImpl<T> extends Chunk<T> { @@ -40,6 +43,7 @@ public class SliceImpl<T> extends Chunk<T> {
super(content, pageable);
this.hasNext = hasNext;
this.pageable = pageable;
}
/**
@ -60,6 +64,15 @@ public class SliceImpl<T> extends Chunk<T> { @@ -60,6 +64,15 @@ public class SliceImpl<T> extends Chunk<T> {
return hasNext;
}
/*
* (non-Javadoc)
* @see org.springframework.data.domain.Slice#transform(org.springframework.core.convert.converter.Converter)
*/
@Override
public <S> Slice<S> map(Converter<? super T, ? extends S> converter) {
return new SliceImpl<S>(getConvertedContent(converter), pageable, hasNext);
}
/*
* (non-Javadoc)
* @see java.lang.Object#toString()

23
src/test/java/org/springframework/data/domain/PageImplUnitTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2008-2014 the original author or authors.
* Copyright 2008-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.
@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
*/
package org.springframework.data.domain;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.data.domain.UnitTestUtils.*;
@ -24,6 +24,7 @@ import java.util.Collections; @@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.springframework.core.convert.converter.Converter;
/**
* Unit test for {@link PageImpl}.
@ -134,4 +135,22 @@ public class PageImplUnitTests { @@ -134,4 +135,22 @@ public class PageImplUnitTests {
public void rejectsTotalLessThanContentLength() {
new PageImpl<String>(Arrays.asList("foo", "bar"), new PageRequest(0, 10), 1);
}
/**
* @see DATACMNS-635
*/
@Test
public void transformsPageCorrectly() {
Page<Integer> transformed = new PageImpl<String>(Arrays.asList("foo", "bar"), new PageRequest(0, 2), 10)
.map(new Converter<String, Integer>() {
@Override
public Integer convert(String source) {
return source.length();
}
});
assertThat(transformed.getContent(), hasSize(2));
assertThat(transformed.getContent(), contains(3, 3));
}
}

Loading…
Cancel
Save