Skip to content

Commit 592a67b

Browse files
committed
DATACMNS-810 - Refactor Query by Example API.
Split Example and ExampleSpec to create reusable components. Refactor builder pattern to a fluent API that creates immutable instances. Split user and framework API, Example and ExampleSpec are user API, created ExampleSpecAccessor for modules to access example spec configuration. Create static methods in GenericPropertyMatchers to ease creation of matchers in a readable style. Convert PropertySpecifier to inner class and move PropertySpecifiers to ExampleSpec.
1 parent 3871379 commit 592a67b

File tree

8 files changed

+1616
-906
lines changed

8 files changed

+1616
-906
lines changed

src/main/java/org/springframework/data/domain/Example.java

Lines changed: 41 additions & 421 deletions
Large diffs are not rendered by default.

src/main/java/org/springframework/data/domain/ExampleSpec.java

Lines changed: 797 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/*
2+
* Copyright 2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.domain;
18+
19+
import java.util.Collection;
20+
21+
/**
22+
* Accessor for the {@link ExampleSpec} to use in modules that support query by example (QBE) querying.
23+
*
24+
* @author Mark Paluch
25+
* @since 1.12
26+
*/
27+
public class ExampleSpecAccessor {
28+
29+
private final ExampleSpec<?> exampleSpec;
30+
31+
public ExampleSpecAccessor(ExampleSpec<?> exampleSpec) {
32+
this.exampleSpec = exampleSpec;
33+
}
34+
35+
/**
36+
* @return unmodifiable {@link Collection} of {@link ExampleSpec.PropertySpecifier}s.
37+
*/
38+
public Collection<ExampleSpec.PropertySpecifier> getPropertySpecifiers() {
39+
return exampleSpec.getPropertySpecifiers().getSpecifiers();
40+
}
41+
42+
/**
43+
* @param path Dot-Path to property.
44+
* @return {@literal true} in case {@link ExampleSpec.PropertySpecifier} defined for given path.
45+
*/
46+
public boolean hasPropertySpecifier(String path) {
47+
return exampleSpec.getPropertySpecifiers().hasSpecifierForPath(path);
48+
}
49+
50+
/**
51+
* Get the {@link ExampleSpec.PropertySpecifier} for given path. <br />
52+
* Please check if {@link #hasPropertySpecifier(String)} to avoid running into {@literal null} values.
53+
*
54+
* @param path Dot-Path to property.
55+
* @return {@literal null} when no {@link ExampleSpec.PropertySpecifier} defined for path.
56+
*/
57+
public ExampleSpec.PropertySpecifier getPropertySpecifier(String path) {
58+
return exampleSpec.getPropertySpecifiers().getForPath(path);
59+
}
60+
61+
/**
62+
* @return true if at least one {@link ExampleSpec.PropertySpecifier} defined.
63+
*/
64+
public boolean hasPropertySpecifiers() {
65+
return exampleSpec.getPropertySpecifiers().hasValues();
66+
}
67+
68+
/**
69+
* Get the {@link ExampleSpec.StringMatcher} for a given path or return the default one if none defined.
70+
*
71+
* @param path
72+
* @return never {@literal null}.
73+
*/
74+
public ExampleSpec.StringMatcher getStringMatcherForPath(String path) {
75+
76+
if (!hasPropertySpecifier(path)) {
77+
return exampleSpec.getDefaultStringMatcher();
78+
}
79+
80+
ExampleSpec.PropertySpecifier specifier = getPropertySpecifier(path);
81+
return specifier.getStringMatcher() != null ? specifier.getStringMatcher() : exampleSpec.getDefaultStringMatcher();
82+
}
83+
84+
/**
85+
* Get defined null handling.
86+
*
87+
* @return never {@literal null}
88+
*/
89+
public ExampleSpec.NullHandler getNullHandler() {
90+
return exampleSpec.getNullHandler();
91+
}
92+
93+
/**
94+
* Get defined {@link ExampleSpec.StringMatcher}.
95+
*
96+
* @return never {@literal null}.
97+
*/
98+
public ExampleSpec.StringMatcher getDefaultStringMatcher() {
99+
return exampleSpec.getDefaultStringMatcher();
100+
}
101+
102+
/**
103+
* @return {@literal true} if {@link String} should be matched with ignore case option.
104+
*/
105+
public boolean isIgnoreCaseEnabled() {
106+
return exampleSpec.isIgnoreCaseEnabled();
107+
}
108+
109+
/**
110+
* @param path
111+
* @return return {@literal true} if path was set to be ignored.
112+
*/
113+
public boolean isIgnoredPath(String path) {
114+
return exampleSpec.isIgnoredPath(path);
115+
}
116+
117+
/**
118+
* Get the ignore case flag for a given path or return the default one if none defined.
119+
*
120+
* @param path
121+
* @return never {@literal null}.
122+
*/
123+
public boolean isIgnoreCaseForPath(String path) {
124+
125+
if (!hasPropertySpecifier(path)) {
126+
return exampleSpec.isIgnoreCaseEnabled();
127+
}
128+
129+
ExampleSpec.PropertySpecifier specifier = getPropertySpecifier(path);
130+
return specifier.getIgnoreCase() != null ? specifier.getIgnoreCase().booleanValue()
131+
: exampleSpec.isIgnoreCaseEnabled();
132+
}
133+
134+
/**
135+
* Get the ignore case flag for a given path or return {@link ExampleSpec.NoOpPropertyValueTransformer} if none
136+
* defined.
137+
*
138+
* @param path
139+
* @return never {@literal null}.
140+
*/
141+
public ExampleSpec.PropertyValueTransformer getValueTransformerForPath(String path) {
142+
143+
if (!hasPropertySpecifier(path)) {
144+
return ExampleSpec.NoOpPropertyValueTransformer.INSTANCE;
145+
}
146+
147+
return getPropertySpecifier(path).getPropertyValueTransformer();
148+
}
149+
150+
public static ExampleSpecAccessor of(Example<?> example) {
151+
return new ExampleSpecAccessor(example.getExampleSpec());
152+
}
153+
154+
public static ExampleSpecAccessor of(ExampleSpec<?> exampleSpec) {
155+
return new ExampleSpecAccessor(exampleSpec);
156+
}
157+
158+
}

0 commit comments

Comments
 (0)