DATACMNS-10 - Introduce method name parser to build criteria based queries.
Minor tweaks to Parameter and Parameters to remove some JPA implications (1-based position indexes). Introduced PartTree abstraction that results from query parsing and allows simple API to traverse the query parts. Added AbstractQueryCreator to implement general traversing logic on PartTree and provide typed callback hooks for persistence technology specific creation of a criteria query.
This commit is contained in:
@@ -103,8 +103,8 @@ public class ParametersUnitTests {
|
||||
|
||||
Parameters parameters = new Parameters(method);
|
||||
|
||||
assertThat(parameters.getParameter(0).getParameterPosition(), is(0));
|
||||
assertThat(parameters.getParameter(1).getParameterPosition(), is(1));
|
||||
assertThat(parameters.getParameter(0).getParameterIndex(), is(-1));
|
||||
assertThat(parameters.getParameter(1).getParameterIndex(), is(0));
|
||||
|
||||
method =
|
||||
SampleDao.class.getMethod("validWithSortInBetween",
|
||||
@@ -112,9 +112,9 @@ public class ParametersUnitTests {
|
||||
|
||||
parameters = new Parameters(method);
|
||||
|
||||
assertThat(parameters.getParameter(0).getParameterPosition(), is(1));
|
||||
assertThat(parameters.getParameter(1).getParameterPosition(), is(0));
|
||||
assertThat(parameters.getParameter(2).getParameterPosition(), is(2));
|
||||
assertThat(parameters.getParameter(0).getParameterIndex(), is(0));
|
||||
assertThat(parameters.getParameter(1).getParameterIndex(), is(-1));
|
||||
assertThat(parameters.getParameter(2).getParameterIndex(), is(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 2008-2010 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.repository.query;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SimpleParameterAccessor}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class SimpleParameterAccessorUnitTests {
|
||||
|
||||
Parameters parameters, sortParameters, pageableParameters;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws SecurityException, NoSuchMethodException {
|
||||
|
||||
parameters =
|
||||
new Parameters(Sample.class.getMethod("sample", String.class));
|
||||
sortParameters =
|
||||
new Parameters(Sample.class.getMethod("sample1", String.class,
|
||||
Sort.class));
|
||||
pageableParameters =
|
||||
new Parameters(Sample.class.getMethod("sample2", String.class,
|
||||
Pageable.class));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testname() throws Exception {
|
||||
|
||||
new SimpleParameterAccessor(parameters, new Object[] { "test" });
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullParameters() throws Exception {
|
||||
|
||||
new SimpleParameterAccessor(null, new Object[0]);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullValues() throws Exception {
|
||||
|
||||
new SimpleParameterAccessor(parameters, null);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsTooLittleNumberOfArguments() throws Exception {
|
||||
|
||||
new SimpleParameterAccessor(parameters, new Object[0]);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsTooManyArguments() throws Exception {
|
||||
|
||||
new SimpleParameterAccessor(parameters, new Object[] { "test", "test" });
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void returnsNullForPageableAndSortIfNoneAvailable() throws Exception {
|
||||
|
||||
SimpleParameterAccessor accessor =
|
||||
new SimpleParameterAccessor(parameters, new Object[] { "test" });
|
||||
assertThat(accessor.getPageable(), is(nullValue()));
|
||||
assertThat(accessor.getSort(), is(nullValue()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void returnsSortIfAvailable() {
|
||||
|
||||
Sort sort = new Sort("foo");
|
||||
SimpleParameterAccessor accessor =
|
||||
new SimpleParameterAccessor(sortParameters, new Object[] {
|
||||
"test", sort });
|
||||
assertThat(accessor.getSort(), is(sort));
|
||||
assertThat(accessor.getPageable(), is(nullValue()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void returnsPageableIfAvailable() {
|
||||
|
||||
Pageable pageable = new PageRequest(0, 10);
|
||||
SimpleParameterAccessor accessor =
|
||||
new SimpleParameterAccessor(pageableParameters, new Object[] {
|
||||
"test", pageable });
|
||||
assertThat(accessor.getPageable(), is(pageable));
|
||||
assertThat(accessor.getSort(), is(nullValue()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void returnsSortFromPageableIfAvailable() throws Exception {
|
||||
|
||||
Sort sort = new Sort("foo");
|
||||
Pageable pageable = new PageRequest(0, 10, sort);
|
||||
SimpleParameterAccessor accessor =
|
||||
new SimpleParameterAccessor(pageableParameters, new Object[] {
|
||||
"test", pageable });
|
||||
assertThat(accessor.getPageable(), is(pageable));
|
||||
assertThat(accessor.getSort(), is(sort));
|
||||
}
|
||||
|
||||
interface Sample {
|
||||
|
||||
void sample(String firstname);
|
||||
|
||||
|
||||
void sample1(String firstname, Sort sort);
|
||||
|
||||
|
||||
void sample2(String firstname, Pageable pageable);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2008-2010 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.repository.query.parser;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.repository.query.parser.PartTree.OrPart;
|
||||
|
||||
|
||||
/**
|
||||
* Unit tests for {@link PartTree}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class PartTreeUnitTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullSource() throws Exception {
|
||||
|
||||
new PartTree(null, getClass());
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNullDomainClass() throws Exception {
|
||||
|
||||
new PartTree("test", null);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsMultipleOrderBy() throws Exception {
|
||||
|
||||
new PartTree("firstnameOrderByLastnameOrderByFirstname", User.class);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void parsesSimplePropertyCorrectly() throws Exception {
|
||||
|
||||
PartTree partTree = new PartTree("firstname", User.class);
|
||||
assertPart(partTree, new Part[] { new Part("firstname", User.class) });
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void parsesAndPropertiesCorrectly() throws Exception {
|
||||
|
||||
PartTree partTree = new PartTree("firstnameAndLastname", User.class);
|
||||
assertPart(partTree, new Part[] { new Part("firstname", User.class),
|
||||
new Part("lastname", User.class) });
|
||||
assertThat(partTree.getSort(), is(nullValue()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void parsesOrPropertiesCorrectly() throws Exception {
|
||||
|
||||
PartTree partTree = new PartTree("firstnameOrLastname", User.class);
|
||||
assertPart(partTree, new Part[] { new Part("firstname", User.class) },
|
||||
new Part[] { new Part("lastname", User.class) });
|
||||
assertThat(partTree.getSort(), is(nullValue()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void hasSortIfOrderByIsGiven() throws Exception {
|
||||
|
||||
PartTree partTree =
|
||||
new PartTree("firstnameOrderByLastnameDesc", User.class);
|
||||
assertThat(partTree.getSort(), is(new Sort(Direction.DESC, "lastname")));
|
||||
}
|
||||
|
||||
|
||||
private void assertPart(PartTree tree, Part[]... parts) {
|
||||
|
||||
Iterator<OrPart> iterator = tree.iterator();
|
||||
for (Part[] part : parts) {
|
||||
assertThat(iterator.hasNext(), is(true));
|
||||
Iterator<Part> partIterator = iterator.next().iterator();
|
||||
for (int k = 0; k < part.length; k++) {
|
||||
assertThat(String.format("Expected %d parts but have %d",
|
||||
part.length, k + 1), partIterator.hasNext(), is(true));
|
||||
Part next = partIterator.next();
|
||||
assertThat(
|
||||
String.format("Expected %s but got %s!", part[k], next),
|
||||
part[k], is(next));
|
||||
}
|
||||
assertThat("Too many parts!", partIterator.hasNext(), is(false));
|
||||
}
|
||||
assertThat("Too many or parts!", iterator.hasNext(), is(false));
|
||||
}
|
||||
|
||||
class User {
|
||||
|
||||
String firstname;
|
||||
String lastname;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user