DATACMNS-621 - QSort now treats nested paths correctly.

We now inspect intermediate path elements to build sort order accordingly.

Original pull request: #111.
This commit is contained in:
Christoph Strobl
2015-01-20 14:19:19 +01:00
committed by Oliver Gierke
parent 2e62a16f69
commit 95bda862e7
5 changed files with 155 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 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.
@@ -19,6 +19,7 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import org.springframework.data.domain.Sort;
import org.springframework.util.Assert;
@@ -31,6 +32,7 @@ import com.mysema.query.types.Path;
* Sort option for queries that wraps a querydsl {@link OrderSpecifier}.
*
* @author Thomas Darimont
* @author Christoph Strobl
*/
public class QSort extends Sort implements Serializable {
@@ -87,8 +89,8 @@ public class QSort extends Sort implements Serializable {
Assert.notNull(orderSpecifier, "Order specifier must not be null!");
Expression<?> target = orderSpecifier.getTarget();
Object targetElement = target instanceof Path ? ((com.mysema.query.types.Path<?>) target).getMetadata()
.getElement() : target;
Object targetElement = target instanceof Path ? preparePropertyPath((Path<?>) target) : target;
Assert.notNull(targetElement, "Target element must not be null!");
@@ -142,4 +144,25 @@ public class QSort extends Sort implements Serializable {
Assert.notEmpty(orderSpecifiers, "OrderSpecifiers must not be null or empty!");
return and(Arrays.asList(orderSpecifiers));
}
private static String preparePropertyPath(Path<?> path) {
Stack<String> stack = new Stack<String>();
Path<?> pathElement = path;
while (pathElement.getMetadata() != null && pathElement.getMetadata().getParent() != null) {
stack.push(pathElement.getMetadata().getElement().toString());
pathElement = pathElement.getMetadata().getParent();
}
StringBuilder sb = new StringBuilder();
while (!stack.isEmpty()) {
sb.append(stack.pop());
if (!stack.isEmpty()) {
sb.append(".");
}
}
return sb.toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 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,9 +15,8 @@
*/
package org.springframework.data.querydsl;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.util.List;
@@ -34,6 +33,7 @@ import com.mysema.query.types.OrderSpecifier;
*
* @author Thomas Darimont
* @author Oliver Gierke
* @author Christoph Strobl
*/
public class QSortUnitTests {
@@ -147,7 +147,7 @@ public class QSortUnitTests {
assertThat(result, is(Matchers.<Order> iterableWithSize(2)));
assertThat(result, hasItems(new Order(Direction.ASC, "lastname"), new Order(Direction.ASC, "firstname")));
}
/**
* @see DATACMNS-566
*/
@@ -159,6 +159,44 @@ public class QSortUnitTests {
Sort result = sort.and(new Sort(Direction.ASC, "lastname"));
assertThat(result, is(Matchers.<Order> iterableWithSize(2)));
assertThat(result, hasItems(new Order(Direction.ASC, "lastname"), new Order(Direction.ASC, user.dateOfBirth.yearMonth().toString())));
assertThat(
result,
hasItems(new Order(Direction.ASC, "lastname"),
new Order(Direction.ASC, user.dateOfBirth.yearMonth().toString())));
}
/**
* @see DATACMNS-621
*/
@Test
public void shouldCreateSortForNestedPathCorrectly() {
QSort sort = new QSort(QUserWrapper.userWrapper.user.firstname.asc());
assertThat(sort, hasItems(new Order(Direction.ASC, "user.firstname")));
}
/**
* @see DATACMNS-621
*/
@Test
public void shouldCreateSortForDeepNestedPathCorrectly() {
QSort sort = new QSort(QWrapperForUserWrapper.wrapperForUserWrapper.wrapper.user.firstname.asc());
assertThat(sort, hasItems(new Order(Direction.ASC, "wrapper.user.firstname")));
}
/**
* @see DATACMNS-621
*/
@Test
public void shouldCreateSortForReallyDeepNestedPathCorrectly() {
QSort sort = new QSort(
QWrapperToWrapWrapperForUserWrapper.wrapperToWrapWrapperForUserWrapper.wrapperForUserWrapper.wrapper.user.firstname
.asc());
assertThat(sort, hasItems(new Order(Direction.ASC, "wrapperForUserWrapper.wrapper.user.firstname")));
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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.querydsl;
import com.mysema.query.annotations.QueryEntity;
/**
* @author Christoph Strobl
*/
@QueryEntity
public class UserWrapper {
User user;
}

View File

@@ -0,0 +1,28 @@
/*
* 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.querydsl;
import com.mysema.query.annotations.QueryEntity;
/**
* @author Christoph Strobl
*/
@QueryEntity
public class WrapperForUserWrapper {
UserWrapper wrapper;
}

View File

@@ -0,0 +1,29 @@
/*
* 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.querydsl;
import com.mysema.query.annotations.QueryEntity;
import com.mysema.query.annotations.QueryInit;
/**
* @author Christoph Strobl
*/
@QueryEntity
public class WrapperToWrapWrapperForUserWrapper {
@QueryInit("wrapper.user")//
WrapperForUserWrapper wrapperForUserWrapper;
}