DATAMONGO-1721 - Polishing.
Removed deprecated types and adapt dependency tests accordingly. Refactored MongoExampleMapper to revert to use StringMatcher from Spring Data Commons' ExampleMatcher. Introduced MongoRegexCreator specific MatchMode, which is basically a copy of StringMatcher. Adapted MongoExampleMapper and MongoQueryCreator to translate from StringMatcher and Part.Type to MatchMode. Turned unit tests for MongoRegexCreator into parameterized ones. Original pull request: #470.
This commit is contained in:
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 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.mongodb.core;
|
|
||||||
|
|
||||||
import org.springframework.data.mongodb.core.geo.GeoJsonModule;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuration class to expose {@link GeoJsonModule} as a Spring bean.
|
|
||||||
*
|
|
||||||
* @author Oliver Gierke
|
|
||||||
* @author Jens Schauder
|
|
||||||
*
|
|
||||||
* @deprecated Use {@link org.springframework.data.mongodb.config.GeoJsonConfiguration} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class GeoJsonConfiguration extends org.springframework.data.mongodb.config.GeoJsonConfiguration {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 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.mongodb.core;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Index operations on a collection.
|
|
||||||
*
|
|
||||||
* @author Mark Pollack
|
|
||||||
* @author Oliver Gierke
|
|
||||||
* @author Christoph Strobl
|
|
||||||
* @author Jens Schauder
|
|
||||||
*
|
|
||||||
* @deprecated Use {@link org.springframework.data.mongodb.core.index.IndexOperations} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface IndexOperations extends org.springframework.data.mongodb.core.index.IndexOperations {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 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.mongodb.core;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Mark Paluch
|
|
||||||
* @author Jens Schauder
|
|
||||||
* @since 2.0
|
|
||||||
*
|
|
||||||
* @deprecated Use {@link org.springframework.data.mongodb.core.index.IndexOperationsProvider} instead.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public interface IndexOperationsProvider extends org.springframework.data.mongodb.core.index.IndexOperationsProvider {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -15,8 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.data.mongodb.core.convert;
|
package org.springframework.data.mongodb.core.convert;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
@@ -29,6 +37,7 @@ import org.springframework.data.mapping.context.MappingContext;
|
|||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
|
||||||
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
||||||
import org.springframework.data.mongodb.core.query.MongoRegexCreator;
|
import org.springframework.data.mongodb.core.query.MongoRegexCreator;
|
||||||
|
import org.springframework.data.mongodb.core.query.MongoRegexCreator.MatchMode;
|
||||||
import org.springframework.data.mongodb.core.query.SerializationUtils;
|
import org.springframework.data.mongodb.core.query.SerializationUtils;
|
||||||
import org.springframework.data.support.ExampleMatcherAccessor;
|
import org.springframework.data.support.ExampleMatcherAccessor;
|
||||||
import org.springframework.data.util.TypeInformation;
|
import org.springframework.data.util.TypeInformation;
|
||||||
@@ -194,7 +203,7 @@ public class MongoExampleMapper {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
org.springframework.data.util.StringMatcher stringMatcher = exampleSpecAccessor.getDefaultStringMatcher().toNewStringMatcher();
|
StringMatcher stringMatcher = exampleSpecAccessor.getDefaultStringMatcher();
|
||||||
Object value = entry.getValue();
|
Object value = entry.getValue();
|
||||||
boolean ignoreCase = exampleSpecAccessor.isIgnoreCaseEnabled();
|
boolean ignoreCase = exampleSpecAccessor.isIgnoreCaseEnabled();
|
||||||
|
|
||||||
@@ -203,7 +212,7 @@ public class MongoExampleMapper {
|
|||||||
mappedPropertyPath = exampleSpecAccessor.hasPropertySpecifier(propertyPath) ? propertyPath
|
mappedPropertyPath = exampleSpecAccessor.hasPropertySpecifier(propertyPath) ? propertyPath
|
||||||
: getMappedPropertyPath(propertyPath, probeType);
|
: getMappedPropertyPath(propertyPath, probeType);
|
||||||
|
|
||||||
stringMatcher = exampleSpecAccessor.getStringMatcherForPath(mappedPropertyPath).toNewStringMatcher();
|
stringMatcher = exampleSpecAccessor.getStringMatcherForPath(mappedPropertyPath);
|
||||||
ignoreCase = exampleSpecAccessor.isIgnoreCaseForPath(mappedPropertyPath);
|
ignoreCase = exampleSpecAccessor.isIgnoreCaseForPath(mappedPropertyPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,12 +241,11 @@ public class MongoExampleMapper {
|
|||||||
return entry.getKey().equals("_id") && entry.getValue() == null || entry.getValue().equals(Optional.empty());
|
return entry.getKey().equals("_id") && entry.getValue() == null || entry.getValue().equals(Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyStringMatcher(Map.Entry<String, Object> entry,
|
private void applyStringMatcher(Map.Entry<String, Object> entry, StringMatcher stringMatcher, boolean ignoreCase) {
|
||||||
org.springframework.data.util.StringMatcher stringMatcher, boolean ignoreCase) {
|
|
||||||
|
|
||||||
Document document = new Document();
|
Document document = new Document();
|
||||||
|
|
||||||
if (org.springframework.data.util.StringMatcher.DEFAULT == stringMatcher) {
|
if (StringMatcher.DEFAULT == stringMatcher) {
|
||||||
|
|
||||||
if (ignoreCase) {
|
if (ignoreCase) {
|
||||||
document.put("$regex", Pattern.quote((String) entry.getValue()));
|
document.put("$regex", Pattern.quote((String) entry.getValue()));
|
||||||
@@ -245,7 +253,8 @@ public class MongoExampleMapper {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
String expression = MongoRegexCreator.INSTANCE.toRegularExpression((String) entry.getValue(), stringMatcher);
|
String expression = MongoRegexCreator.INSTANCE.toRegularExpression((String) entry.getValue(),
|
||||||
|
toMatchMode(stringMatcher));
|
||||||
document.put("$regex", expression);
|
document.put("$regex", expression);
|
||||||
entry.setValue(document);
|
entry.setValue(document);
|
||||||
}
|
}
|
||||||
@@ -255,7 +264,28 @@ public class MongoExampleMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private org.springframework.data.util.StringMatcher convert(StringMatcher stringMatcher) {
|
/**
|
||||||
return org.springframework.data.util.StringMatcher.valueOf(stringMatcher.name());
|
* Return the {@link MatchMode} for the given {@link StringMatcher}.
|
||||||
|
*
|
||||||
|
* @param matcher must not be {@literal null}.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static MatchMode toMatchMode(StringMatcher matcher) {
|
||||||
|
|
||||||
|
switch (matcher) {
|
||||||
|
case CONTAINING:
|
||||||
|
return MatchMode.CONTAINING;
|
||||||
|
case STARTING:
|
||||||
|
return MatchMode.STARTING_WITH;
|
||||||
|
case ENDING:
|
||||||
|
return MatchMode.ENDING_WITH;
|
||||||
|
case EXACT:
|
||||||
|
return MatchMode.EXACT;
|
||||||
|
case REGEX:
|
||||||
|
return MatchMode.REGEX;
|
||||||
|
case DEFAULT:
|
||||||
|
default:
|
||||||
|
return MatchMode.DEFAULT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ package org.springframework.data.mongodb.core.query;
|
|||||||
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.springframework.data.repository.query.parser.Part.Type;
|
|
||||||
import org.springframework.data.util.StringMatcher;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christoph Strobl
|
* @author Christoph Strobl
|
||||||
* @author Mark Paluch
|
* @author Mark Paluch
|
||||||
@@ -30,22 +27,49 @@ public enum MongoRegexCreator {
|
|||||||
|
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
private static final Pattern PUNCTATION_PATTERN = Pattern.compile("\\p{Punct}");
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a regular expression String to be used with {@code $regex}.
|
* Match modes for treatment of {@link String} values.
|
||||||
*
|
*
|
||||||
* @param source the plain String
|
* @author Christoph Strobl
|
||||||
* @param type
|
* @author Jens Schauder
|
||||||
* @return {@literal source} when {@literal source} or {@literal type} is {@literal null}.
|
|
||||||
* @deprecated use the {@link MongoRegexCreator#toRegularExpression(String, StringMatcher)} instead
|
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
public enum MatchMode {
|
||||||
public String toRegularExpression(String source, Type type) {
|
|
||||||
|
|
||||||
return toRegularExpression(source, convert(type));
|
/**
|
||||||
|
* Store specific default.
|
||||||
|
*/
|
||||||
|
DEFAULT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches the exact string
|
||||||
|
*/
|
||||||
|
EXACT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches string starting with pattern
|
||||||
|
*/
|
||||||
|
STARTING_WITH,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches string ending with pattern
|
||||||
|
*/
|
||||||
|
ENDING_WITH,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Matches string containing pattern
|
||||||
|
*/
|
||||||
|
CONTAINING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Treats strings as regular expression patterns
|
||||||
|
*/
|
||||||
|
REGEX,
|
||||||
|
|
||||||
|
LIKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Pattern PUNCTATION_PATTERN = Pattern.compile("\\p{Punct}");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a regular expression String to be used with {@code $regex}.
|
* Creates a regular expression String to be used with {@code $regex}.
|
||||||
*
|
*
|
||||||
@@ -53,7 +77,7 @@ public enum MongoRegexCreator {
|
|||||||
* @param matcherType the type of matching to perform
|
* @param matcherType the type of matching to perform
|
||||||
* @return {@literal source} when {@literal source} or {@literal matcherType} is {@literal null}.
|
* @return {@literal source} when {@literal source} or {@literal matcherType} is {@literal null}.
|
||||||
*/
|
*/
|
||||||
public String toRegularExpression(String source, StringMatcher matcherType) {
|
public String toRegularExpression(String source, MatchMode matcherType) {
|
||||||
|
|
||||||
if (matcherType == null || source == null) {
|
if (matcherType == null || source == null) {
|
||||||
return source;
|
return source;
|
||||||
@@ -62,30 +86,26 @@ public enum MongoRegexCreator {
|
|||||||
String regex = prepareAndEscapeStringBeforeApplyingLikeRegex(source, matcherType);
|
String regex = prepareAndEscapeStringBeforeApplyingLikeRegex(source, matcherType);
|
||||||
|
|
||||||
switch (matcherType) {
|
switch (matcherType) {
|
||||||
case STARTING:
|
case STARTING_WITH:
|
||||||
regex = "^" + regex;
|
return String.format("^%s", regex);
|
||||||
break;
|
case ENDING_WITH:
|
||||||
case ENDING:
|
return String.format("%s$", regex);
|
||||||
regex = regex + "$";
|
|
||||||
break;
|
|
||||||
case CONTAINING:
|
case CONTAINING:
|
||||||
regex = ".*" + regex + ".*";
|
return String.format(".*%s.*", regex);
|
||||||
break;
|
|
||||||
case EXACT:
|
case EXACT:
|
||||||
regex = "^" + regex + "$";
|
return String.format("^%s$", regex);
|
||||||
default:
|
default:
|
||||||
|
return regex;
|
||||||
}
|
}
|
||||||
|
|
||||||
return regex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String prepareAndEscapeStringBeforeApplyingLikeRegex(String source, StringMatcher matcherType) {
|
private String prepareAndEscapeStringBeforeApplyingLikeRegex(String source, MatchMode matcherType) {
|
||||||
|
|
||||||
if (StringMatcher.REGEX == matcherType) {
|
if (MatchMode.REGEX == matcherType) {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringMatcher.LIKE != matcherType) {
|
if (MatchMode.LIKE != matcherType) {
|
||||||
return PUNCTATION_PATTERN.matcher(source).find() ? Pattern.quote(source) : source;
|
return PUNCTATION_PATTERN.matcher(source).find() ? Pattern.quote(source) : source;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,57 +128,13 @@ public enum MongoRegexCreator {
|
|||||||
if (leadingWildcard) {
|
if (leadingWildcard) {
|
||||||
sb.append(".*");
|
sb.append(".*");
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.append(valueToUse);
|
sb.append(valueToUse);
|
||||||
|
|
||||||
if (trailingWildcard) {
|
if (trailingWildcard) {
|
||||||
sb.append(".*");
|
sb.append(".*");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringMatcher convert(Type type) {
|
|
||||||
|
|
||||||
if (type == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
|
|
||||||
case NOT_LIKE:
|
|
||||||
case LIKE:
|
|
||||||
return StringMatcher.LIKE;
|
|
||||||
case STARTING_WITH:
|
|
||||||
return StringMatcher.STARTING;
|
|
||||||
case ENDING_WITH:
|
|
||||||
return StringMatcher.ENDING;
|
|
||||||
case NOT_CONTAINING:
|
|
||||||
case CONTAINING:
|
|
||||||
return StringMatcher.CONTAINING;
|
|
||||||
case REGEX:
|
|
||||||
return StringMatcher.REGEX;
|
|
||||||
case SIMPLE_PROPERTY:
|
|
||||||
case NEGATING_SIMPLE_PROPERTY:
|
|
||||||
return StringMatcher.EXACT;
|
|
||||||
case BETWEEN:
|
|
||||||
case IS_NOT_NULL:
|
|
||||||
case IS_NULL:
|
|
||||||
case LESS_THAN:
|
|
||||||
case LESS_THAN_EQUAL:
|
|
||||||
case GREATER_THAN:
|
|
||||||
case GREATER_THAN_EQUAL:
|
|
||||||
case BEFORE:
|
|
||||||
case AFTER:
|
|
||||||
case EXISTS:
|
|
||||||
case TRUE:
|
|
||||||
case FALSE:
|
|
||||||
case NOT_IN:
|
|
||||||
case IN:
|
|
||||||
case NEAR:
|
|
||||||
case WITHIN:
|
|
||||||
case IS_NOT_EMPTY:
|
|
||||||
case IS_EMPTY:
|
|
||||||
return StringMatcher.DEFAULT;
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Execution should never reach this position.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
|
|||||||
import org.springframework.data.mongodb.core.query.Criteria;
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
|
||||||
import org.springframework.data.mongodb.core.query.MongoRegexCreator;
|
import org.springframework.data.mongodb.core.query.MongoRegexCreator;
|
||||||
|
import org.springframework.data.mongodb.core.query.MongoRegexCreator.MatchMode;
|
||||||
import org.springframework.data.mongodb.core.query.Query;
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
import org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator;
|
import org.springframework.data.mongodb.repository.query.ConvertingParameterAccessor.PotentiallyConvertingIterator;
|
||||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||||
@@ -402,7 +403,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String toLikeRegex(String source, Part part) {
|
private String toLikeRegex(String source, Part part) {
|
||||||
return MongoRegexCreator.INSTANCE.toRegularExpression(source, part.getType());
|
return MongoRegexCreator.INSTANCE.toRegularExpression(source, toMatchMode(part.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSpherical(MongoPersistentProperty property) {
|
private boolean isSpherical(MongoPersistentProperty property) {
|
||||||
@@ -414,4 +415,27 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MatchMode toMatchMode(Type type) {
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case NOT_CONTAINING:
|
||||||
|
case CONTAINING:
|
||||||
|
return MatchMode.CONTAINING;
|
||||||
|
case STARTING_WITH:
|
||||||
|
return MatchMode.STARTING_WITH;
|
||||||
|
case ENDING_WITH:
|
||||||
|
return MatchMode.ENDING_WITH;
|
||||||
|
case LIKE:
|
||||||
|
case NOT_LIKE:
|
||||||
|
return MatchMode.LIKE;
|
||||||
|
case REGEX:
|
||||||
|
return MatchMode.REGEX;
|
||||||
|
case NEGATING_SIMPLE_PROPERTY:
|
||||||
|
case SIMPLE_PROPERTY:
|
||||||
|
return MatchMode.EXACT;
|
||||||
|
default:
|
||||||
|
return MatchMode.DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,32 +18,26 @@ package org.springframework.data.mongodb;
|
|||||||
import static de.schauderhaft.degraph.check.JCheck.*;
|
import static de.schauderhaft.degraph.check.JCheck.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.springframework.data.mongodb.core.GeoJsonConfiguration;
|
|
||||||
import org.springframework.data.mongodb.core.query.MongoRegexCreator;
|
|
||||||
|
|
||||||
import de.schauderhaft.degraph.configuration.NamedPattern;
|
import de.schauderhaft.degraph.configuration.NamedPattern;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests package dependency constraints.
|
* Tests package dependency constraints.
|
||||||
*
|
*
|
||||||
* @author Jens Schauder
|
* @author Jens Schauder
|
||||||
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
public class DependencyTests {
|
public class DependencyTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noInternalPackageCycles() {
|
public void noInternalPackageCycles() {
|
||||||
|
|
||||||
assertThat(
|
assertThat(classpath() //
|
||||||
classpath() //
|
.noJars() //
|
||||||
.noJars() //
|
.including("org.springframework.data.mongodb.**") //
|
||||||
.including("org.springframework.data.mongodb.**") //
|
.filterClasspath("*target/classes") //
|
||||||
// ignoring deprecated class that will be removed soon
|
.printOnFailure("degraph.graphml"), //
|
||||||
.excluding(org.springframework.data.mongodb.core.IndexOperations.class.getCanonicalName())
|
|
||||||
.excluding(org.springframework.data.mongodb.core.IndexOperationsProvider.class.getCanonicalName())
|
|
||||||
.excluding(GeoJsonConfiguration.class.getCanonicalName())
|
|
||||||
.filterClasspath("*target/classes") //
|
|
||||||
.printOnFailure("degraph.graphml"), //
|
|
||||||
violationFree() //
|
violationFree() //
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -51,24 +45,16 @@ public class DependencyTests {
|
|||||||
@Test
|
@Test
|
||||||
public void onlyConfigMayUseRepository() {
|
public void onlyConfigMayUseRepository() {
|
||||||
|
|
||||||
assertThat(
|
assertThat(classpath() //
|
||||||
classpath() //
|
.including("org.springframework.data.**") //
|
||||||
.including("org.springframework.data.**") //
|
.filterClasspath("*target/classes") //
|
||||||
// ignoring the MongoRegexCreator for now, since it still
|
.printOnFailure("onlyConfigMayUseRepository.graphml") //
|
||||||
// needs the reference to Part.Type to maintain the old API
|
.withSlicing("slices", //
|
||||||
.excluding(MongoRegexCreator.class.getCanonicalName() + "*")
|
"**.(config).**", //
|
||||||
// ignoring deprecated class that will be removed soon
|
new NamedPattern("**.cdi.**", "config"), //
|
||||||
.excluding(org.springframework.data.mongodb.core.IndexOperations.class.getCanonicalName())
|
"**.(repository).**", //
|
||||||
.excluding(org.springframework.data.mongodb.core.IndexOperationsProvider.class.getCanonicalName())
|
new NamedPattern("**", "other"))
|
||||||
.excluding(GeoJsonConfiguration.class.getCanonicalName())
|
.allow("config", "repository", "other"), //
|
||||||
.filterClasspath("*target/classes") //
|
|
||||||
.printOnFailure("onlyConfigMayUseRepository.graphml") //
|
|
||||||
.withSlicing("slices", //
|
|
||||||
"**.(config).**", //
|
|
||||||
new NamedPattern("**.cdi.**", "config"), //
|
|
||||||
"**.(repository).**", //
|
|
||||||
new NamedPattern("**", "other"))
|
|
||||||
.allow("config", "repository", "other"), //
|
|
||||||
violationFree() //
|
violationFree() //
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -76,13 +62,12 @@ public class DependencyTests {
|
|||||||
@Test
|
@Test
|
||||||
public void commonsInternaly() {
|
public void commonsInternaly() {
|
||||||
|
|
||||||
assertThat(
|
assertThat(classpath() //
|
||||||
classpath() //
|
.noJars() //
|
||||||
.noJars() //
|
.including("org.springframework.data.**") //
|
||||||
.including("org.springframework.data.**") //
|
.excluding("org.springframework.data.mongodb.**") //
|
||||||
.excluding("org.springframework.data.mongodb.**") //
|
.filterClasspath("*target/classes") //
|
||||||
.filterClasspath("*target/classes") //
|
.printTo("commons.graphml"), //
|
||||||
.printTo("commons.graphml"), //
|
|
||||||
violationFree() //
|
violationFree() //
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,116 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 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.mongodb.core.query;
|
package org.springframework.data.mongodb.core.query;
|
||||||
|
|
||||||
import static java.util.Arrays.*;
|
import static java.util.Arrays.*;
|
||||||
|
import static org.assertj.core.api.Assertions.*;
|
||||||
import static org.springframework.data.mongodb.core.query.MongoRegexCreatorUnitTests.TestParameter.*;
|
import static org.springframework.data.mongodb.core.query.MongoRegexCreatorUnitTests.TestParameter.*;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.assertj.core.api.SoftAssertions;
|
|
||||||
import org.assertj.core.api.StringAssert;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.data.repository.query.parser.Part.Type;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.junit.runners.Parameterized.Parameter;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
import org.springframework.data.mongodb.core.query.MongoRegexCreator.MatchMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the creation of Regex's in {@link MongoRegexCreator}
|
* Tests the creation of Regex's in {@link MongoRegexCreator}
|
||||||
*
|
*
|
||||||
* @author Jens Schauder
|
* @author Jens Schauder
|
||||||
|
* @author Oliver Gierke
|
||||||
*/
|
*/
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
public class MongoRegexCreatorUnitTests {
|
public class MongoRegexCreatorUnitTests {
|
||||||
|
|
||||||
List<TestParameter> testParameters = asList(TestParameter.test("anystring", null, "anystring", "type=null -> input"),
|
@Parameters(name = "{index}: {0}") //
|
||||||
test(null, Type.AFTER, null, "source=null -> null"), //
|
public static List<TestParameter> parameters() {
|
||||||
test("anystring", Type.REGEX, "anystring", "REGEX -> input"), //
|
|
||||||
test("one.two?three", Type.AFTER, "\\Qone.two?three\\E",
|
|
||||||
"not(REGEX, LIKE, NOT_LIKE, PunctuationPattern -> quoted punctuation"), //
|
|
||||||
test("*", Type.LIKE, ".*", "LIKE * -> .*"), test("*", Type.NOT_LIKE, ".*", "LIKE * -> .*"), //
|
|
||||||
test("*.*", Type.LIKE, ".*\\Q.\\E.*", "Wildcards & Punctuation"), //
|
|
||||||
test("*.", Type.LIKE, ".*\\Q.\\E", "Leading Wildcard & Punctuation"), //
|
|
||||||
test(".*", Type.LIKE, "\\Q.\\E.*", "Trailing Wildcard & Punctuation"), //
|
|
||||||
test("other", Type.LIKE, "other", "No Wildcard & Other"), //
|
|
||||||
test("other*", Type.LIKE, "other.*", "Trailing Wildcard & Other"), //
|
|
||||||
test("*other", Type.LIKE, ".*other", "Leading Wildcard & Other"), //
|
|
||||||
test("o*t.*h.er", Type.LIKE, "\\Qo*t.*h.er\\E", "Dots & Stars"), //
|
|
||||||
test("other", Type.STARTING_WITH, "^other", "Dots & Stars"), //
|
|
||||||
test("other", Type.ENDING_WITH, "other$", "Dots & Stars"), //
|
|
||||||
test("other", Type.CONTAINING, ".*other.*", "Dots & Stars"), //
|
|
||||||
test("other", Type.NOT_CONTAINING, ".*other.*", "Dots & Stars"), //
|
|
||||||
test("other", Type.SIMPLE_PROPERTY, "^other$", "Dots & Stars"), //
|
|
||||||
test("other", Type.NEGATING_SIMPLE_PROPERTY, "^other$", "Dots & Stars"));
|
|
||||||
|
|
||||||
Map<Type, String> expectedResultsForAllTypes = new HashMap<>();
|
|
||||||
{
|
|
||||||
expectedResultsForAllTypes.put(Type.BETWEEN, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.IS_NOT_NULL, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.IS_NULL, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.LESS_THAN, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.LESS_THAN_EQUAL, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.GREATER_THAN, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.GREATER_THAN_EQUAL, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.BEFORE, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.AFTER, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.NOT_LIKE, "\\Qo*t.*h.er\\E.*");
|
|
||||||
expectedResultsForAllTypes.put(Type.LIKE, "\\Qo*t.*h.er\\E.*");
|
|
||||||
expectedResultsForAllTypes.put(Type.STARTING_WITH, "^\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.ENDING_WITH, "\\Qo*t.*h.er*\\E$");
|
|
||||||
expectedResultsForAllTypes.put(Type.IS_NOT_EMPTY, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.IS_EMPTY, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.NOT_CONTAINING, ".*\\Qo*t.*h.er*\\E.*");
|
|
||||||
expectedResultsForAllTypes.put(Type.CONTAINING, ".*\\Qo*t.*h.er*\\E.*");
|
|
||||||
expectedResultsForAllTypes.put(Type.NOT_IN, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.IN, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.NEAR, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.WITHIN, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.REGEX, "o*t.*h.er*");
|
|
||||||
expectedResultsForAllTypes.put(Type.EXISTS, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.TRUE, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.FALSE, "\\Qo*t.*h.er*\\E");
|
|
||||||
expectedResultsForAllTypes.put(Type.NEGATING_SIMPLE_PROPERTY, "^\\Qo*t.*h.er*\\E$");
|
|
||||||
expectedResultsForAllTypes.put(Type.SIMPLE_PROPERTY, "^\\Qo*t.*h.er*\\E$");
|
|
||||||
|
|
||||||
|
return asList(//
|
||||||
|
test(null, MatchMode.EXACT, null, "Null input string -> null"), //
|
||||||
|
test("anystring", null, "anystring", "type=null -> input"), //
|
||||||
|
test("anystring", MatchMode.REGEX, "anystring", "REGEX -> input"), //
|
||||||
|
test("*", MatchMode.LIKE, ".*", "LIKE * -> .*"), //
|
||||||
|
test("*.*", MatchMode.LIKE, ".*\\Q.\\E.*", "Wildcards & Punctuation"), //
|
||||||
|
test("*.", MatchMode.LIKE, ".*\\Q.\\E", "Leading Wildcard & Punctuation"), //
|
||||||
|
test(".*", MatchMode.LIKE, "\\Q.\\E.*", "Trailing Wildcard & Punctuation"), //
|
||||||
|
test("other", MatchMode.LIKE, "other", "No Wildcard & Other"), //
|
||||||
|
test("other*", MatchMode.LIKE, "other.*", "Trailing Wildcard & Other"), //
|
||||||
|
test("*other", MatchMode.LIKE, ".*other", "Leading Wildcard & Other"), //
|
||||||
|
test("o*t.*h.er", MatchMode.LIKE, "\\Qo*t.*h.er\\E", "Dots & Stars"), //
|
||||||
|
test("other", MatchMode.STARTING_WITH, "^other", "Dots & Stars"), //
|
||||||
|
test("other", MatchMode.ENDING_WITH, "other$", "Dots & Stars"), //
|
||||||
|
test("other", MatchMode.CONTAINING, ".*other.*", "Dots & Stars"), //
|
||||||
|
test("other", MatchMode.EXACT, "^other$", "Dots & Stars"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Parameter(0) //
|
||||||
|
public TestParameter parameter;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSpecialCases() {
|
public void testSpecialCases() {
|
||||||
SoftAssertions.assertSoftly(sa -> testParameters.forEach(tp -> tp.check(sa)));
|
parameter.check();
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAllTypes() {
|
|
||||||
SoftAssertions.assertSoftly(
|
|
||||||
sa -> Arrays.stream(Type.values()).forEach(t -> //
|
|
||||||
test("o*t.*h.er*", t, expectedResultsForAllTypes.getOrDefault(t,"missed one"), t.toString())//
|
|
||||||
.check(sa)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@lombok.RequiredArgsConstructor(staticName = "test")
|
||||||
static class TestParameter {
|
static class TestParameter {
|
||||||
|
|
||||||
TestParameter(String source, Type type, String expectedResult, String comment) {
|
|
||||||
this.source = source;
|
|
||||||
this.type = type;
|
|
||||||
this.expectedResult = expectedResult;
|
|
||||||
this.comment = comment;
|
|
||||||
}
|
|
||||||
|
|
||||||
static TestParameter test(String source, Type type, String expectedResult, String comment) {
|
|
||||||
return new TestParameter(source, type, expectedResult, comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String source;
|
private final String source;
|
||||||
private final Type type;
|
private final MatchMode mode;
|
||||||
private final String expectedResult;
|
private final String expectedResult, comment;
|
||||||
private final String comment;
|
|
||||||
|
|
||||||
private StringAssert check(SoftAssertions sa) {
|
void check() {
|
||||||
|
|
||||||
return sa
|
assertThat(MongoRegexCreator.INSTANCE.toRegularExpression(source, mode))//
|
||||||
.assertThat( //
|
.as(comment)//
|
||||||
MongoRegexCreator.INSTANCE.toRegularExpression(source, type)) //
|
|
||||||
.describedAs(comment) //
|
|
||||||
.isEqualTo(expectedResult);
|
.isEqualTo(expectedResult);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.format("Mode: %s, %s", mode, comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user