diff --git a/src/main/java/org/springframework/data/jpa/repository/query/DeclaredQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/DeclaredQuery.java index b67f4b9c9..9aadc2e7f 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/DeclaredQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/DeclaredQuery.java @@ -24,6 +24,7 @@ import org.springframework.util.StringUtils; * A wrapper for a String representation of a query offering information about the query. * * @author Jens Schauder + * @since 2.0.3 */ interface DeclaredQuery { @@ -31,7 +32,6 @@ interface DeclaredQuery { * Creates a {@literal DeclaredQuery} from a query {@literal String}. * * @param query might be {@literal null} or empty. - * * @return a {@literal DeclaredQuery} instance even for a {@literal null} or empty argument. */ static DeclaredQuery of(@Nullable String query) { @@ -80,8 +80,7 @@ interface DeclaredQuery { * * @param countQuery an optional query string to be used if present. * @param countQueryProjection an optional return type for the query. - * @return A new {@literal DeclaredQuery} instance. + * @return a new {@literal DeclaredQuery} instance. */ DeclaredQuery deriveCountQuery(@Nullable String countQuery, @Nullable String countQueryProjection); - } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/EmptyDeclaredQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/EmptyDeclaredQuery.java index e8a8d495a..34f273e25 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/EmptyDeclaredQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/EmptyDeclaredQuery.java @@ -15,16 +15,17 @@ */ package org.springframework.data.jpa.repository.query; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - import java.util.Collections; import java.util.List; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + /** - * NULL-Object pattern implementation. + * NULL-Object pattern implementation for {@link DeclaredQuery}. * * @author Jens Schauder + * @since 2.0.3 */ class EmptyDeclaredQuery implements DeclaredQuery { @@ -33,36 +34,64 @@ class EmptyDeclaredQuery implements DeclaredQuery { */ static final DeclaredQuery EMPTY_QUERY = new EmptyDeclaredQuery(); + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#hasNamedParameter() + */ @Override public boolean hasNamedParameter() { return false; } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#getQueryString() + */ @Override public String getQueryString() { return ""; } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#getAlias() + */ @Override public String getAlias() { return null; } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#hasConstructorExpression() + */ @Override public boolean hasConstructorExpression() { return false; } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#isDefaultProjection() + */ @Override public boolean isDefaultProjection() { return false; } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#getParameterBindings() + */ @Override public List getParameterBindings() { return Collections.emptyList(); } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#deriveCountQuery(java.lang.String, java.lang.String) + */ @Override public DeclaredQuery deriveCountQuery(@Nullable String countQuery, @Nullable String countQueryProjection) { diff --git a/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinderFactory.java b/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinderFactory.java index 4e16d3371..bc6ac6d04 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinderFactory.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinderFactory.java @@ -124,7 +124,7 @@ class ParameterBinderFactory { } private static Iterable createSetters(List parameterBindings, - DeclaredQuery declaredQuery, QueryParameterSetterFactory... strategies) { + DeclaredQuery declaredQuery, QueryParameterSetterFactory... strategies) { return parameterBindings.stream() // .map(it -> createQueryParameterSetter(it, strategies, declaredQuery)) // diff --git a/src/main/java/org/springframework/data/jpa/repository/query/QuotationMap.java b/src/main/java/org/springframework/data/jpa/repository/query/QuotationMap.java deleted file mode 100644 index 5830815dc..000000000 --- a/src/main/java/org/springframework/data/jpa/repository/query/QuotationMap.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2018 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.jpa.repository.query; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.springframework.data.domain.Range; -import org.springframework.lang.Nullable; - -/** - * Datastructure that analyses a String to determine the parts of the String that are quoted and offers an API to query - * that information. - * - * @author Jens Schauder - */ -class QuotationMap { - - private static final Set QUOTING_CHARACTERS = new HashSet<>(Arrays.asList('"', '\'')); - private List> quotedRanges = new ArrayList<>(); - - QuotationMap(@Nullable String query) { - - if (query == null) - return; - - Character inQuotation = null; - int start = 0; - - for (int i = 0; i < query.length(); i++) { - - char currentChar = query.charAt(i); - if (QUOTING_CHARACTERS.contains(currentChar)) { - - if (inQuotation == null) { - - inQuotation = currentChar; - start = i; - } else if (currentChar == inQuotation) { - - inQuotation = null; - quotedRanges.add(Range.of(Range.Bound.inclusive(start), Range.Bound.inclusive(i))); - } - } - } - - if (inQuotation != null) { - throw new IllegalArgumentException( - String.format("The string <%s> starts a quoted range at %d, but never ends it.", query, start)); - } - } - - /** - * @param index to check if it is part of a quoted range. - * @return whether the query contains a quoted range at {@literal index}. - */ - public boolean isQuoted(int index) { - return quotedRanges.stream().anyMatch(r -> r.contains(index)); - } -} diff --git a/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java index 5c2f4e6f8..5e58b01ce 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/StringQuery.java @@ -22,10 +22,13 @@ import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.springframework.data.domain.Range; import org.springframework.data.repository.query.parser.Part.Type; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -75,13 +78,23 @@ class StringQuery implements DeclaredQuery { return !bindings.isEmpty(); } - /** - * Returns the {@link ParameterBinding}s registered. + String getProjection() { + return QueryUtils.getProjection(query); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#getParameterBindings() */ + @Override public List getParameterBindings() { return bindings; } + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#deriveCountQuery(java.lang.String, java.lang.String) + */ @Override public DeclaredQuery deriveCountQuery(@Nullable String countQuery, @Nullable String countQueryProjection) { @@ -89,18 +102,18 @@ class StringQuery implements DeclaredQuery { .of(countQuery != null ? countQuery : QueryUtils.createCountQueryFor(query, countQueryProjection)); } - /** - * Returns the query string. + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#getQueryString() */ @Override public String getQueryString() { return query; } - /** - * Returns the main alias used in the query. - * - * @return the alias + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#getAlias() */ @Override @Nullable @@ -108,33 +121,31 @@ class StringQuery implements DeclaredQuery { return alias; } - /** - * Returns whether the query is using a constructor expression. - * - * @since 1.10 + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#hasConstructorExpression() */ @Override public boolean hasConstructorExpression() { return hasConstructorExpression; } - /** - * Returns whether the query uses the default projection, i.e. returns the main alias defined for the query. + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#isDefaultProjection() */ @Override public boolean isDefaultProjection() { return getProjection().equals(alias); } - public String getProjection() { - return QueryUtils.getProjection(query); - } - + /* + * (non-Javadoc) + * @see org.springframework.data.jpa.repository.query.DeclaredQuery#hasNamedParameter() + */ @Override public boolean hasNamedParameter() { - - return bindings.stream() // - .anyMatch(b -> b.getName() != null); + return bindings.stream().anyMatch(b -> b.getName() != null); } /** @@ -760,4 +771,59 @@ class StringQuery implements DeclaredQuery { } } + /** + * Value object to analyze a String to determine the parts of the String that are quoted and offers an API to query + * that information. + * + * @author Jens Schauder + * @since 3.0.3 + */ + static class QuotationMap { + + private static final Set QUOTING_CHARACTERS = new HashSet<>(Arrays.asList('"', '\'')); + + private List> quotedRanges = new ArrayList<>(); + + QuotationMap(@Nullable String query) { + + if (query == null) { + return; + } + + Character inQuotation = null; + int start = 0; + + for (int i = 0; i < query.length(); i++) { + + char currentChar = query.charAt(i); + + if (QUOTING_CHARACTERS.contains(currentChar)) { + + if (inQuotation == null) { + + inQuotation = currentChar; + start = i; + + } else if (currentChar == inQuotation) { + + inQuotation = null; + quotedRanges.add(Range.of(Range.Bound.inclusive(start), Range.Bound.inclusive(i))); + } + } + } + + if (inQuotation != null) { + throw new IllegalArgumentException( + String.format("The string <%s> starts a quoted range at %d, but never ends it.", query, start)); + } + } + + /** + * @param index to check if it is part of a quoted range. + * @return whether the query contains a quoted range at {@literal index}. + */ + public boolean isQuoted(int index) { + return quotedRanges.stream().anyMatch(r -> r.contains(index)); + } + } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/package-info.java b/src/main/java/org/springframework/data/jpa/repository/query/package-info.java index 4d7c118fd..efbf2d7af 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/package-info.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/package-info.java @@ -1,5 +1,5 @@ /** - * Query implementation to exectue queries against JPA. + * Query implementation to execute queries against JPA. */ @org.springframework.lang.NonNullApi package org.springframework.data.jpa.repository.query; diff --git a/src/test/java/org/springframework/data/jpa/repository/query/QuotationMapUnitTests.java b/src/test/java/org/springframework/data/jpa/repository/query/QuotationMapUnitTests.java index b5ed12079..b71bb6f57 100644 --- a/src/test/java/org/springframework/data/jpa/repository/query/QuotationMapUnitTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/query/QuotationMapUnitTests.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import org.assertj.core.api.SoftAssertions; import org.junit.Test; +import org.springframework.data.jpa.repository.query.StringQuery.QuotationMap; /** * Unit tests for {@link QuotationMap}.