diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameter.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameter.java index c1a4626f1..b02429fc3 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameter.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameter.java @@ -21,6 +21,7 @@ import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.List; +import org.springframework.core.MethodParameter; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.util.Assert; @@ -32,7 +33,7 @@ import org.springframework.util.Assert; * * @author Oliver Gierke */ -public final class Parameter { +public class Parameter { @SuppressWarnings("unchecked") static final List> TYPES = Arrays.asList(Pageable.class, @@ -46,11 +47,8 @@ public final class Parameter { private static final String NAMED_PARAMETER_TEMPLATE = ":%s"; private static final String POSITION_PARAMETER_TEMPLATE = "?%s"; - private final Class type; private final Parameters parameters; - private final int index; - private final String name; - + private final MethodParameter parameter; /** * Creates a new {@link Parameter} for the given type, {@link Annotation}s, @@ -61,16 +59,13 @@ public final class Parameter { * @param index * @param name */ - Parameter(Class type, Parameters parameters, int index, String name) { + protected Parameter(MethodParameter parameter, Parameters parameters) { - Assert.notNull(type); + Assert.notNull(parameter); Assert.notNull(parameters); + this.parameter = parameter; this.parameters = parameters; - this.index = index; - - this.type = type; - this.name = name; if (isSpecialParameter() && isNamedParameter()) { throw new IllegalArgumentException(PARAM_ON_SPECIAL); @@ -85,7 +80,7 @@ public final class Parameter { */ boolean isFirst() { - return index == 0; + return getIndex() == 0; } @@ -98,7 +93,7 @@ public final class Parameter { */ public Parameter getNext() { - return parameters.getParameter(index + 1); + return parameters.getParameter(getIndex() + 1); } @@ -109,7 +104,7 @@ public final class Parameter { */ Parameter getPrevious() { - return parameters.getParameter(index - 1); + return parameters.getParameter(getIndex() - 1); } @@ -122,7 +117,7 @@ public final class Parameter { */ public boolean isSpecialParameter() { - return TYPES.contains(type); + return TYPES.contains(parameter.getParameterType()); } @@ -162,7 +157,7 @@ public final class Parameter { */ public int getIndex() { - return index; + return parameter.getParameterIndex(); } @@ -185,8 +180,8 @@ public final class Parameter { * @return */ public String getName() { - - return name; + Param annotation = parameter.getParameterAnnotation(Param.class); + return annotation == null ? parameter.getParameterName() : annotation.value(); } @@ -196,19 +191,18 @@ public final class Parameter { * @return the type */ public Class getType() { - return type; + return parameter.getParameterType(); } /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ + * (non-Javadoc) + * @see java.lang.Object#toString() + */ @Override public String toString() { - return format("%s:%s", isNamedParameter() ? getName() : "#" + index, - type.getName()); + return format("%s:%s", isNamedParameter() ? getName() : "#" + getIndex(), + getType().getName()); } @@ -219,7 +213,7 @@ public final class Parameter { */ boolean isPageable() { - return Pageable.class.isAssignableFrom(type); + return Pageable.class.isAssignableFrom(getType()); } @@ -230,6 +224,6 @@ public final class Parameter { */ boolean isSort() { - return Sort.class.isAssignableFrom(type); + return Sort.class.isAssignableFrom(getType()); } } diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameters.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameters.java index bf0d3c59d..95788ea1c 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameters.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/Parameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2010 the original author or authors. + * Copyright 2008-2011 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,6 @@ */ package org.springframework.data.repository.query; -import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; @@ -23,6 +22,7 @@ import java.util.Iterator; import java.util.List; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; +import org.springframework.core.MethodParameter; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -35,7 +35,7 @@ import org.springframework.util.Assert; * * @author Oliver Gierke */ -public final class Parameters implements Iterable { +public class Parameters implements Iterable { @SuppressWarnings("unchecked") public static final List> TYPES = Arrays.asList(Pageable.class, @@ -70,8 +70,9 @@ public final class Parameters implements Iterable { List> types = Arrays.asList(method.getParameterTypes()); for (int i = 0; i < types.size(); i++) { - String name = getParameterName(method, i); - parameters.add(new Parameter(types.get(i), this, i, name)); + MethodParameter parameter = new MethodParameter(method, i); + parameter.initParameterNameDiscovery(discoverer); + parameters.add(createParameter(parameter)); } this.pageableIndex = types.indexOf(Pageable.class); @@ -81,33 +82,6 @@ public final class Parameters implements Iterable { } - /** - * Returns the name of the parameter of the given {@link Method} with the - * given index. Inspects {@link Param} annotation before falling back to a - * {@link ParameterNameDiscoverer}. - * - * @param method - * @param index - * @return - */ - private String getParameterName(Method method, int index) { - - for (Annotation annotation : method.getParameterAnnotations()[index]) { - if (annotation instanceof Param) { - return ((Param) annotation).value(); - } - } - - String[] parameterNames = discoverer.getParameterNames(method); - - if (parameterNames != null) { - return parameterNames[index]; - } - - return null; - } - - /** * Creates a new {@link Parameters} instance with the given * {@link Parameter}s put into new context. @@ -133,6 +107,10 @@ public final class Parameters implements Iterable { this.pageableIndex = pageableIndexTemp; this.sortIndex = sortIndexTemp; } + + protected Parameter createParameter(MethodParameter parameter) { + return new Parameter(parameter, this); + } /** diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java index 64a4e9383..d44a288db 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/ParametersParameterAccessor.java @@ -83,6 +83,17 @@ public class ParametersParameterAccessor implements ParameterAccessor { return null; } + + /** + * Returns the value with the given index. + * + * @param index + * @return + */ + @SuppressWarnings("unchecked") + protected T getValue(int index) { + return (T) values[index]; + } /* diff --git a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java index e2a3db1c4..bd4d21cf4 100644 --- a/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java +++ b/spring-data-commons-core/src/main/java/org/springframework/data/repository/query/QueryMethod.java @@ -53,10 +53,12 @@ public class QueryMethod { * correct query to use for following invocations of the method given. * * @param method must not be {@literal null} + * @param metadata must not be {@literal null} */ public QueryMethod(Method method, RepositoryMetadata metadata) { Assert.notNull(method, "Method must not be null!"); + Assert.notNull(metadata, "Repository metadata must not be null!"); for (Class type : Parameters.TYPES) { if (getNumberOfOccurences(method, type) > 1) { @@ -76,9 +78,19 @@ public class QueryMethod { } this.method = method; - this.parameters = new Parameters(method); + this.parameters = getParameters(); this.metadata = metadata; } + + /** + * Creates a {@link Parameters} instance. + * + * @param method + * @return + */ + protected Parameters createParameters(Method method) { + return new Parameters(method); + } /** diff --git a/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java b/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java index 13a022950..d6221883d 100644 --- a/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java +++ b/spring-data-commons-core/src/test/java/org/springframework/data/repository/query/ParametersUnitTests.java @@ -121,6 +121,18 @@ public class ParametersUnitTests { Parameters parameters = getParametersFor("emptyParameters"); assertThat(parameters.hasParameterAt(0), is(false)); } + + @Test + public void detectsPageableParameter() throws Exception { + Parameters parameters = getParametersFor("validWithPageable", String.class, Pageable.class); + assertThat(parameters.getPageableIndex(), is(1)); + } + + @Test + public void detectsSortParameter() throws Exception { + Parameters parameters = getParametersFor("validWithSort", String.class, Sort.class); + assertThat(parameters.getSortIndex(), is(1)); + } private Parameters getParametersFor(String methodName,