DATAJPA-702 - Added simplified JpaSort.and(…).
Added new ….and(…) methods to JpaSort to take a Direction and Paths or Attributes to allow more concise definition of additional orders. Slightly changed the method signature for methods on Path taking a Plural attribute to satisfy the compiler.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-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.
|
||||
@@ -62,7 +62,7 @@ public class JpaSort extends Sort {
|
||||
* @param attributes must not be {@literal null} or empty.
|
||||
*/
|
||||
public JpaSort(Direction direction, Attribute<?, ?>... attributes) {
|
||||
this(direction, paths(Arrays.asList(attributes)));
|
||||
this(direction, paths(attributes));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,12 +71,50 @@ public class JpaSort extends Sort {
|
||||
* @param direction the sorting direction.
|
||||
* @param paths must not be {@literal null} or empty.
|
||||
*/
|
||||
public JpaSort(Direction direction, JpaSort.Path<?, ?>... paths) {
|
||||
public JpaSort(Direction direction, Path<?, ?>... paths) {
|
||||
this(direction, Arrays.asList(paths));
|
||||
}
|
||||
|
||||
private JpaSort(Direction direction, List<JpaSort.Path<?, ?>> paths) {
|
||||
super(direction, toString(paths));
|
||||
private JpaSort(Direction direction, List<Path<?, ?>> paths) {
|
||||
this(Collections.<Order> emptyList(), direction, paths);
|
||||
}
|
||||
|
||||
private JpaSort(List<Order> orders, Direction direction, List<Path<?, ?>> paths) {
|
||||
super(combine(orders, direction, paths));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link JpaSort} with the given sorting criteria added to the current one.
|
||||
*
|
||||
* @param direction can be {@literal null}.
|
||||
* @param attributes must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public JpaSort and(Direction direction, Attribute<?, ?>... attributes) {
|
||||
|
||||
Assert.notNull(attributes, "Attributes must not be null!");
|
||||
|
||||
return and(direction, paths(attributes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link JpaSort} with the given sorting criteria added to the current one.
|
||||
*
|
||||
* @param direction can be {@literal null}.
|
||||
* @param paths must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public JpaSort and(Direction direction, Path<?, ?>... paths) {
|
||||
|
||||
Assert.notNull(paths, "Paths must not be null!");
|
||||
|
||||
List<Order> existing = new ArrayList<Order>();
|
||||
|
||||
for (Order order : this) {
|
||||
existing.add(order);
|
||||
}
|
||||
|
||||
return new JpaSort(existing, direction, Arrays.asList(paths));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,35 +123,29 @@ public class JpaSort extends Sort {
|
||||
* @param attributes must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
private static List<Path<?, ?>> paths(List<? extends Attribute<?, ?>> attributes) {
|
||||
private static Path<?, ?>[] paths(Attribute<?, ?>[] attributes) {
|
||||
|
||||
Assert.notNull(attributes, "Attributes must not be null!");
|
||||
Assert.isTrue(!attributes.isEmpty(), "Attributes must not be empty");
|
||||
Assert.isTrue(attributes.length > 0, "Attributes must not be empty");
|
||||
|
||||
List<Path<?, ?>> paths = new ArrayList<Path<?, ?>>(attributes.size());
|
||||
Path<?, ?>[] paths = new Path[attributes.length];
|
||||
|
||||
for (Attribute<?, ?> attribute : attributes) {
|
||||
paths.add(path(attribute));
|
||||
for (int i = 0; i < attributes.length; i++) {
|
||||
paths[i] = path(attributes[i]);
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the given {@link Path}s into a {@link String} array.
|
||||
*
|
||||
* @param paths must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
private static String[] toString(List<Path<?, ?>> paths) {
|
||||
private static List<Order> combine(List<Order> orders, Direction direction, List<Path<?, ?>> paths) {
|
||||
|
||||
List<String> strings = new ArrayList<String>(paths.size());
|
||||
List<Order> result = new ArrayList<Sort.Order>(orders);
|
||||
|
||||
for (Path<?, ?> path : paths) {
|
||||
strings.add(path.toString());
|
||||
result.add(new Order(direction, path.toString()));
|
||||
}
|
||||
|
||||
return strings.toArray(new String[strings.size()]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,12 +155,10 @@ public class JpaSort extends Sort {
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, S> Path<T, S> path(Attribute<T, S> attribute) {
|
||||
public static <A extends Attribute<T, S>, T, S> Path<T, S> path(A attribute) {
|
||||
|
||||
Assert.notNull(attribute, "Attribute must not be null!");
|
||||
|
||||
List<? extends Attribute<?, ?>> attributes = Arrays.asList(attribute);
|
||||
return new Path<T, S>(attributes);
|
||||
return new Path<T, S>(Arrays.asList(attribute));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,12 +168,10 @@ public class JpaSort extends Sort {
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T, S> Path<T, S> path(PluralAttribute<T, ?, S> attribute) {
|
||||
public static <P extends PluralAttribute<T, ?, S>, T, S> Path<T, S> path(P attribute) {
|
||||
|
||||
Assert.notNull(attribute, "Attribute must not be null!");
|
||||
|
||||
List<? extends Attribute<?, ?>> attributes = Arrays.asList(attribute);
|
||||
return new Path<T, S>(attributes);
|
||||
return new Path<T, S>(Arrays.asList(attribute));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,17 +193,17 @@ public class JpaSort extends Sort {
|
||||
* @param attribute must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public <U> Path<S, U> dot(Attribute<S, U> attribute) {
|
||||
public <A extends Attribute<S, U>, U> Path<S, U> dot(A attribute) {
|
||||
return new Path<S, U>(add(attribute));
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the given {@link Attribute} and returning a new {@link Path} pointing to the attribute type.
|
||||
* Collects the given {@link PluralAttribute} and returning a new {@link Path} pointing to the attribute type.
|
||||
*
|
||||
* @param attribute must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public <U> Path<S, U> dot(PluralAttribute<S, ?, U> attribute) {
|
||||
public <P extends PluralAttribute<S, ?, U>, U> Path<S, U> dot(P attribute) {
|
||||
return new Path<S, U>(add(attribute));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-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,8 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.jpa.domain;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.domain.Sort.Direction.*;
|
||||
import static org.springframework.data.jpa.domain.JpaSort.*;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
@@ -27,9 +28,12 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.domain.Sort.Order;
|
||||
import org.springframework.data.jpa.domain.JpaSort.Path;
|
||||
import org.springframework.data.jpa.domain.sample.Address_;
|
||||
import org.springframework.data.jpa.domain.sample.MailMessage_;
|
||||
import org.springframework.data.jpa.domain.sample.MailSender_;
|
||||
import org.springframework.data.jpa.domain.sample.Role_;
|
||||
import org.springframework.data.jpa.domain.sample.User_;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -81,50 +85,92 @@ public class JpaSortTests {
|
||||
|
||||
@Test
|
||||
public void sortByMultiplePropertiesWithDefaultSortDirection() {
|
||||
|
||||
assertThat(new JpaSort(User_.firstname, User_.lastname),
|
||||
hasItems(new Sort.Order("firstname"), new Sort.Order("lastname")));
|
||||
assertThat(new JpaSort(User_.firstname, User_.lastname), hasItems(new Order("firstname"), new Order("lastname")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sortByMultiplePropertiesWithDescSortDirection() {
|
||||
|
||||
assertThat(new JpaSort(Direction.DESC, User_.firstname, User_.lastname),
|
||||
hasItems(new Sort.Order(Direction.DESC, "firstname"), new Sort.Order(Direction.DESC, "lastname")));
|
||||
assertThat(new JpaSort(DESC, User_.firstname, User_.lastname),
|
||||
hasItems(new Order(DESC, "firstname"), new Order(Direction.DESC, "lastname")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combiningSortByMultipleProperties() {
|
||||
|
||||
assertThat(new JpaSort(User_.firstname).and(new JpaSort(User_.lastname)),
|
||||
hasItems(new Sort.Order("firstname"), new Sort.Order("lastname")));
|
||||
hasItems(new Order("firstname"), new Order("lastname")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combiningSortByMultiplePropertiesWithDifferentSort() {
|
||||
|
||||
assertThat(new JpaSort(User_.firstname).and(new JpaSort(Direction.DESC, User_.lastname)),
|
||||
hasItems(new Sort.Order("firstname"), new Sort.Order(Direction.DESC, "lastname")));
|
||||
assertThat(new JpaSort(User_.firstname).and(new JpaSort(DESC, User_.lastname)),
|
||||
hasItems(new Order("firstname"), new Order(DESC, "lastname")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combiningSortByNestedEmbeddedProperty() {
|
||||
|
||||
assertThat(new JpaSort(path(User_.address).dot(Address_.streetName)),
|
||||
hasItems(new Sort.Order("address.streetName")));
|
||||
assertThat(new JpaSort(path(User_.address).dot(Address_.streetName)), hasItems(new Order("address.streetName")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildJpaSortFromJpaMetaModelSingleAttribute() {
|
||||
|
||||
assertThat(new JpaSort(Direction.ASC, path(User_.firstname)), //
|
||||
hasItems(new Sort.Order("firstname")));
|
||||
assertThat(new JpaSort(ASC, path(User_.firstname)), //
|
||||
hasItems(new Order("firstname")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildJpaSortFromJpaMetaModelNestedAttribute() {
|
||||
|
||||
assertThat(new JpaSort(Direction.ASC, path(MailMessage_.mailSender).dot(MailSender_.name)),
|
||||
hasItems(new Sort.Order("mailSender.name")));
|
||||
assertThat(new JpaSort(ASC, path(MailMessage_.mailSender).dot(MailSender_.name)), //
|
||||
hasItems(new Order("mailSender.name")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-702
|
||||
*/
|
||||
@Test
|
||||
public void combiningSortByMultiplePropertiesWithDifferentSortUsingSimpleAnd() {
|
||||
|
||||
assertThat(new JpaSort(User_.firstname).and(DESC, User_.lastname),
|
||||
contains(new Order("firstname"), new Order(DESC, "lastname")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-702
|
||||
*/
|
||||
@Test
|
||||
public void combiningSortByMultiplePathsWithDifferentSortUsingSimpleAnd() {
|
||||
|
||||
assertThat(new JpaSort(User_.firstname).and(DESC, path(MailMessage_.mailSender).dot(MailSender_.name)),
|
||||
contains(new Order("firstname"), new Order(DESC, "mailSender.name")));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-702
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullAttributesForCombiningCriterias() {
|
||||
new JpaSort(User_.firstname).and(DESC, (Attribute<?, ?>[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-702
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullPathsForCombiningCriterias() {
|
||||
new JpaSort(User_.firstname).and(DESC, (Path<?, ?>[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-702
|
||||
*/
|
||||
@Test
|
||||
public void buildsUpPathForPluralAttributesCorrectly() {
|
||||
|
||||
assertThat(new JpaSort(path(User_.colleagues).dot(User_.roles).dot(Role_.name)), //
|
||||
hasItem(new Order(ASC, "colleagues.roles.name")));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user